validates_presence_of导致after_initialize被一个奇怪的自我调用
我有这个模型工作正常:
class Weight < ActiveRecord::Base belongs_to :user validates_presence_of :weight, :measured_on attr_accessible :weight, :measured_on def after_initialize self.measured_on ||= Date.today end end
我添加了这一行
validates_uniqueness_of :measured_on, :scope => :user_id
它开始在validation时抛出错误。 不是validation错误,而是Ruby错误:
>> w.valid? ActiveRecord::MissingAttributeError: missing attribute: measured_on from /Users/pupeno/Projects/sano/app/models/weight.rb:8:in `after_initialize'
我在after_initialize中放了一个调试器语句,我注意到了一些意想不到的事情。 当我创建一个新的权重时,它按预期工作,after_initialize上的self对象是预期的权重:
>> w = Weight.new /Users/pupeno/Projects/sano/app/models/weight.rb:9 self.measured_on ||= Date.today (rdb:1) p self # (rdb:1) c => #
当我运行w.valid? 这很奇怪。 再次调用after_initialize,我不知道为什么,自我对象不是我所期望的:
>> w.valid? /Users/pupeno/Projects/sano/app/models/weight.rb:9 self.measured_on ||= Date.today (rdb:1) p self # (rdb:1) p self.inspect "#" (rdb:1) p self.class Weight(id: integer, user_id: integer, weight: float, measured_on: date, created_at: datetime, updated_at: datetime) (rdb:1) p self.measured_on ActiveRecord::MissingAttributeError Exception: missing attribute: measured_on (rdb:1)
似乎另一个Weight对象创建时没有任何属性,但id设置。 有什么想法吗? 这是一个错误还是预期的行为? 我是通过在after_initialize上设置measured_on做错了吗?
我目前的解决方法是,如果有人遇到同样的问题,那就是
class Weight :user_id attr_accessible :weight, :measured_on def after_initialize if self.has_attribute? :measured_on self.measured_on ||= Date.today end end end
但我想有一个合适的解决方案。
我认为你正在遇到我最近与之斗争的铁轨问题。 请参阅此博客条目链接到相关的灯塔错误。
我的理解是,正在发生的事情是,一些先前的rails代码执行“select table from tablename”以查看条目是否存在或匹配。 然后,该对象缓存表中唯一存在的字段是“id”。 然后运行您的代码,然后“属性”值不正确,仅反映id字段。
从我能找到的情况来看,这只发生在这个特定的代码路径被击中时,除了进行validation时,通常不会让事情发生。
我所做的是将after_initialise代码包装在begin / rescue ActiveRecord :: MissingAttributeError块中。 然后我在应用程序中写了一个大笔记,并在每个项目上面指出何时发布新版本的rails,我们可以删除它。
是的,我确信有更优雅的解决方案。
def after_initialize begin # ... updates here # self.unique_reference = UUIDTools::UUID.random_create.to_s rescue ActiveRecord::MissingAttributeError end end
或者你也可以这样做:
def after_initialize if self.has_attribute? :measured_on self.measured_on ||= Date.today end end
此问题与rails票证#3165有关。 如果您对如何以及为何发生这种情况感兴趣,请在那里阅读
在我终于找到那张票之前,我只花了半天时间。 虽然我很遗憾,自报道以来已经差不多整整一年了,而且还没有修复,这是我的简单解决方案:
validates_uniqueness_of :email, :scope => :library_id def after_initialize self.status ||= "Invited" end
如果validates_uniqueness_of查询返回了记录,则会引发“MissingAttributeError”。 我的简单解决方案是:
def after_initialize self.status ||= "Invited" if new_record? end
虽然其他人遇到了更复杂的问题,但这应该解决简单的情况,直到实际的解决方案被提交到rails。
validates_uniqueness_of需要扫描数据库以查找条目。 ActiveRecord正在将所有其他条目作为模型实例加载。 但是为了减少处理器/内存的使用,它不会为属性添加方法,因为它不需要它们来进行快速存在检查。 但是,它仍然将所有现有记录实例化为模型的实例,因此调用after_initialize。
解决方法是直接修改@attributes哈希,而不是依赖于访问者:
class Weight < ActiveRecord::Base belongs_to :user validates_presence_of :weight, :measured_on validates_uniqueness_of :measured_on, :scope => :user_id attr_accessible :weight, :measured_on def after_initialize @attributes["measured_on"] ||= Date.today end end
- Rails 4 jQuery,javascript和咖啡脚本无法正常工作
- 如何使用belongs_to / has_many关系在Active Admin索引中显示关联模型的属性(Rails 3.2 / Active Admin)
- 纸张跟踪手动版本控制无法按预期工作
- Rails 4.1和Bootstrap 3 glyphicons无法正常工作
- 如何在ruby中优化Two_sum代码的解决方案
- PDF不包含带有pdf-reader的EOF标记(PDF :: Reader :: MalformedPDFError)
- undefined方法`’为nil:NilClass for Rails模型为new
- 使用slim或haml在独立(非rails)ruby应用程序中指定布局和模板
- 通过rails中的链接获取标题,内容