2010-09-14 54 views
3

使用Rails 2.3.2(目前不能很好地升级)使用ruby 1.8.7(2009-06-12 patchlevel 174)[universal -darwin10.0。如果验证是:on => :update,则在对模型进行验证时尝试保存时出现以下错误。如果我将验证更改为:on => :create并创建新记录,则看不到该错误,并且如果没有验证,则保存它并没有问题。Rails/Active Record FAILSAFE错误“用户无法引用”

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实例已保存,但在此特定情况下,foobar之前很久以前已保存过,但未验证(保存未经验证,这是正常的可能状态,因为它是数据从部分保存数据的多页形式,用户可以返回并在稍后修正完成)。

+0

这似乎不是保存你正在更新的对象的问题,而是似乎是持续存在于会话中的任何问题。作为此更新操作的一部分,您是否在会话中存储了某些内容?当验证失败时,可能值得发布导致错误的验证以及您正在使用的参数。 – Shadwell 2010-09-14 22:05:55

+0

刚刚更新了这个信息的问题。谢谢!我最困惑的是为什么这个问题现在正在发生,只有:on =>:更新验证,而不是:on =>:创建验证。我开始怀疑ApplicationController中的require要比通过一个大的class_eval定义更新方法,尽管这是永远存在的,我会认为它会在BarfooController类中重新定义。 – 2010-09-15 19:20:45

回答

1

继续开发模型后多一点我开始另一个错误:

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

我试图保存在控制台中的模式和成功,但看到了一些奇怪的事情。当我已经在模型上设置了有效的foobar时,它要求foobar_id有效(例如)。所以,我和一个团队成员谈论了这件事,并且听说他已经阅读了关于试图验证这样的关联对象的id的问题。

我删除:

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

和它的工作。

但是,它是由另一同事,我是有这个问题,很可能涉及到做validates_presence_of :foobar_id的时候,在控制器中,我试图设置foobar向我建议:

barfoo.foobar = foobar 

,而不是设置foobar_id,如:

barfoor.foobar_id = foobar.id 

我也注意到,与前例子,它没有在数据库中的相关行中设置foobar_id

将它更改为foobar_id设置为barfoo后,只要没有更新验证,它就会保存在创建和更新中。但是,如果我添加验证:on => :update,它会失败。

0

我在这里很晚。但我也有同样的问题,我得到了一个临时的解决办法为它

只是覆盖在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 

名帅方法简单,它会重新加载所有的ActiveRecord对象存在于会话变量

相关问题