加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – validates_presence_of导致after_initialize被

发布时间:2020-12-17 03:33:42 所属栏目:百科 来源:网络整理
导读:我有这个模型工作正常: 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 endend 我添加了这一行 validates_un
我有这个模型工作正常:

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

它开始在验证时抛出错误.不是验证错误,而是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
#<Weight id: nil,user_id: nil,weight: nil,measured_on: nil,created_at: nil,updated_at: nil>
(rdb:1) c
=> #<Weight id: nil,measured_on: "2009-11-22",updated_at: nil>

当我运行w.valid?它变得奇怪.再次调用after_initialize,我不知道为什么,自我对象不是我所期望的:

>> w.valid?
/Users/pupeno/Projects/sano/app/models/weight.rb:9
self.measured_on ||= Date.today
(rdb:1) p self
#<Weight id: 1>
(rdb:1) p self.inspect
"#<Weight id: 1>"
(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 < 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
    if self.has_attribute? :measured_on
      self.measured_on ||= Date.today
    end
  end
end

但我想有一个合适的解决方案.

解决方法

我认为你正在遇到我最近与之斗争的铁轨问题.请参阅 This blog entry链接到相关的灯塔错误.

我的理解是,正在发生的事情是,一些先前的rails代码执行“select table from tablename”以查看条目是否存在或匹配.然后,该对象缓存表中唯一存在的字段是“id”.然后运行您的代码,然后“属性”值不正确,仅反映id字段.

从我能找到的情况来看,这只发生在这个特定的代码路径被击中时,除了进行验证时,通常不会让事情发生.

我所做的是将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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读