代码之家  ›  专栏  ›  技术社区  ›  Gary S. Weaver

Rails/Active Record故障保护错误“无法引用用户”

  •  3
  • Gary S. Weaver  · 技术社区  · 14 年前

    使用rails2.3.2(目前还不适合升级)和ruby 1.8.7(2009-06-12 patchlevel174)[universal-darwin10.0]。在对模型执行验证时尝试保存时出现以下错误(如果验证失败) :on => :update . 如果我把验证改成 :on => :create

    Completed in 392ms (View: 10, DB: 296) | 200 OK [http://localhost/barfoos/update]
    /!\ FAILSAFE /!\  Tue Sep 14 16:38:49 -0400 2010
      Status: 500 Internal Server Error
      User can't be referred
        /path/to/project/vendor/rails/activerecord/lib/active_record/session_store.rb:67:in `dump'
        /path/to/project/vendor/rails/activerecord/lib/active_record/session_store.rb:67:in `marshal'
        /path/to/project/vendor/rails/activerecord/lib/active_record/session_store.rb:123:in `marshal_data!'
        /path/to/project/vendor/rails/activesupport/lib/active_support/callbacks.rb:178:in `send'
        /path/to/project/vendor/rails/activesupport/lib/active_support/callbacks.rb:178:in `evaluate_method'
        /path/to/project/vendor/rails/activesupport/lib/active_support/callbacks.rb:166:in `call'
        /path/to/project/vendor/rails/activesupport/lib/active_support/callbacks.rb:93:in `run'
        /path/to/project/vendor/rails/activesupport/lib/active_support/callbacks.rb:92:in `each'
        /path/to/project/vendor/rails/activesupport/lib/active_support/callbacks.rb:92:in `send'
        /path/to/project/vendor/rails/activesupport/lib/active_support/callbacks.rb:92:in `run'
        /path/to/project/vendor/rails/activesupport/lib/active_support/callbacks.rb:276:in `run_callbacks'
        /path/to/project/vendor/rails/activerecord/lib/active_record/callbacks.rb:344:in `callback'
        /path/to/project/vendor/rails/activerecord/lib/active_record/callbacks.rb:249:in `create_or_update'
        /path/to/project/vendor/rails/activerecord/lib/active_record/base.rb:2539:in `save_without_validation'
        /path/to/project/vendor/rails/activerecord/lib/active_record/validations.rb:1009:in `save_without_dirty'
        /path/to/project/vendor/rails/activerecord/lib/active_record/dirty.rb:79:in `save_without_transactions'
        /path/to/project/vendor/rails/activerecord/lib/active_record/transactions.rb:229:in `send'
        /path/to/project/vendor/rails/activerecord/lib/active_record/transactions.rb:229:in `with_transaction_returning_status'
        /path/to/project/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
        /path/to/project/vendor/rails/activerecord/lib/active_record/transactions.rb:182:in `transaction'
        /path/to/project/vendor/rails/activerecord/lib/active_record/transactions.rb:228:in `with_transaction_returning_status'
        /path/to/project/vendor/rails/activerecord/lib/active_record/transactions.rb:196:in `save_without_unsaved_flag'
        /path/to/project/vendor/rails/activerecord/lib/active_record/transactions.rb:208:in `rollback_active_record_state!'
        /path/to/project/vendor/rails/activerecord/lib/active_record/transactions.rb:196:in `save_without_unsaved_flag'
        /path/to/project/vendor/plugins/active_scaffold/lib/extensions/unsaved_record.rb:15:in `save'
        /path/to/project/vendor/rails/activerecord/lib/active_record/session_store.rb:300:in `set_session'
        /path/to/project/vendor/rails/activerecord/lib/active_record/base.rb:1453:in `silence'
        /path/to/project/vendor/rails/activerecord/lib/active_record/session_store.rb:297:in `set_session'
        /path/to/project/vendor/rails/actionpack/lib/action_controller/session/abstract_store.rb:132:in `call'
        /path/to/project/vendor/rails/activerecord/lib/active_record/query_cache.rb:29:in `call'
        /path/to/project/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:34:in `cache'
        /path/to/project/vendor/rails/activerecord/lib/active_record/query_cache.rb:9:in `cache'
        /path/to/project/vendor/rails/activerecord/lib/active_record/query_cache.rb:28:in `call'
        /path/to/project/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb:361:in `call'
        /path/to/project/vendor/rails/actionpack/lib/action_controller/reloader.rb:9:in `call'
        /path/to/project/vendor/rails/actionpack/lib/action_controller/failsafe.rb:11:in `call'
        /Library/Ruby/Gems/1.8/gems/rack-1.0.1/lib/rack/lock.rb:11:in `call'
        /Library/Ruby/Gems/1.8/gems/rack-1.0.1/lib/rack/lock.rb:11:in `synchronize'
        /Library/Ruby/Gems/1.8/gems/rack-1.0.1/lib/rack/lock.rb:11:in `call'
        /path/to/project/vendor/rails/actionpack/lib/action_controller/dispatcher.rb:106:in `call'
        /path/to/project/vendor/rails/railties/lib/rails/rack/static.rb:31:in `call'
        /Library/Ruby/Gems/1.8/gems/rack-1.0.1/lib/rack/urlmap.rb:46:in `call'
        /Library/Ruby/Gems/1.8/gems/rack-1.0.1/lib/rack/urlmap.rb:40:in `each'
        /Library/Ruby/Gems/1.8/gems/rack-1.0.1/lib/rack/urlmap.rb:40:in `call'
        /path/to/project/vendor/rails/railties/lib/rails/rack/log_tailer.rb:17:in `call'
        /Library/Ruby/Gems/1.8/gems/rack-1.0.1/lib/rack/content_length.rb:13:in `call'
        /Library/Ruby/Gems/1.8/gems/rack-1.0.1/lib/rack/handler/webrick.rb:50:in `service'
        /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
        /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
        /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
        /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
        /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
        /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
        /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
        /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
        /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
        /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
        /Library/Ruby/Gems/1.8/gems/rack-1.0.1/lib/rack/handler/webrick.rb:14:in `run'
        /path/to/project/vendor/rails/railties/lib/commands/server.rb:111
        /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
        /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `require'
        script/server:3
    

    模型如下所示:

    class Barfoo < ActiveRecord::Base
      default_scope :conditions => {:scoping_model_id => ScopingModel.current_version.id}
      belongs_to :scoping_model
    
      # validate is false to keep from attempting to validate Foobar on Barfoo save, as Foobar can be saved, even if invalid, unlike Barfoo.
      has_one :foobar, :validate => false
      validates_presence_of :foobar_id, :on => :create, :message => "can't be blank"
      validates_inclusion_of :accepted_an_agreement, :in => [true, false], :on => :update, :message => "please choose whether you agree or disagree"
      validates_presence_of :some_option_string, :on => :update, :message => "before agreeing, you must specify the some string", :if => Proc.new { |detail| detail.accepted_an_agreement == true }
      validates_presence_of :some_text, :on => :update, :message => "you must provide details if option is 'Other'", :if => Proc.new { |detail| detail.some_option_string == 'Other' }
    end
    

    我所指定的这些字段的值并不重要 Shadwell 他在下面的评论中指出,这似乎与会议有关。我们在ApplicationController中所做的一件与会话相关和与用户相关的事情可能会导致这个问题,尽管它以前从来都不是问题。ApplicationController看起来像:

    class ApplicationController < ActionController::Base
      include ExceptionNotifiable
      require 'something_that_defines_update_method_that_we_redefine_in_controller'
      include Userstamp
    
      ActionController::Base.session_options[:httponly] = true
      ActionController::Base.session_options[:secure] = true
    
      prepend_before_filter :user_setting_method
    
      ...
    
      protected
    
      def user_setting_method
        session[:username] ||= optional_override_username
        session[:username] = session[:username]  # touch the session for timeout purposes
        @user ||= User.find_by_username session[:username]
        true
      end
    
      ...
    
    end
    

    搜索并没有带来太多关于 /!\ FAILSAFE /!\ User can't be referred . 关于什么会导致这种情况,有没有共同的解决办法,或者寻找可能是错误的东西?

    请注意 foobar 实例,但在这种情况下, 福巴 以前已保存,但未验证(保存时未验证,这是一种正常的可能状态,因为它是来自多页表单的数据,部分保存数据,用户可以稍后返回并更正以完成)。

    2 回复  |  直到 8 年前
        1
  •  1
  •   Gary S. Weaver    14 年前

    在继续进一步开发模型之后,我开始出现另一个错误:

    /!\ FAILSAFE /!\  Fri Sep 17 14:53:50 -0400 2010
      Status: 500 Internal Server Error
      can't dump hash with default proc
    

    foobar_id 当我已经设置了一个有效的 foobar 在模型上。所以,我和一个团队成员讨论了这个问题,听说他读到了一些问题,试图验证一个相关对象的id。

    我删除了:

    validates_presence_of :foobar_id, :on => :create, :message => "can't be blank"
    

    而且成功了。

    但是,另一位同事向我建议,我遇到的问题可能与工作有关 validates_presence_of :foobar_id ,当时,在控制器中,我试图设置 福巴

    barfoo.foobar = foobar
    

    foobar\u标识 比如:

    barfoor.foobar_id = foobar.id
    

    我还注意到,在前一个例子中,情况并不是这样 foobar\u标识 在数据库的相关行中。

    barfoo ,似乎只要没有更新验证,就可以在创建和更新时保存。但是,如果我添加验证 :on => :update

        2
  •  0
  •   Siva    11 年前

    我来晚了。但我也有同样的问题,我得到了一个临时的解决办法

    只需重写 activerecord/lib/active_record/session_store.rb

    ActiveRecord::SessionStore::ClassMethods.module_eval do
      def marshal(data)
        # To prevent from Marshal dump error
        begin       
          ::Base64.encode64(Marshal.dump(data)) if data
        rescue      
          # Checks for any ActiveRecord object in session variables and reloads it
          data.each_pair do |key,obj|
            if obj.is_a?(ActiveRecord::Base) || obj.is_a?(Array)
              unless obj.is_a?(Array)       
                data[key] = obj.reload              
                next                                
              end                           
              data[key].collect do |it_obj| 
                if obj.is_a?(ActiveRecord::Base)    
                  it_obj.reload                             
                else                                
                  it_obj                                    
                end                                 
              end                           
            end                     
          end               
          ::Base64.encode64(Marshal.dump(data)) if data
        end         
    
      end   
    end