0

我在 Rails 中遇到了一个奇怪的问题。我想在 Rails 的模型中设置字段的值,但我做不到,即使在 Rails 控制台中也是如此。观察:

1.9.3p393 :008 > campy = Campaign.last
  Campaign Load (0.8ms)  SELECT `campaigns`.* FROM `campaigns` ORDER BY `campaigns`.`id` DESC LIMIT 1
 => #<Campaign id: 3, name: "Stuff", ..., approved_at: nil, approval_requested_at: nil> 
1.9.3p393 :009 > campy.approved_at = Time.now
 => 2013-07-01 00:54:38 +0200 
1.9.3p393 :010 > campy.save
   (0.2ms)  BEGIN
   (0.2ms)  COMMIT
 => true 
1.9.3p393 :011 > campy.approved_at
 => 2013-07-01 00:54:38 +0200 
1.9.3p393 :012 > Campaign.last.approved_at
  Campaign Load (0.7ms)  SELECT `campaigns`.* FROM `campaigns` ORDER BY `campaigns`.`id` DESC LIMIT 1
 => nil 
1.9.3p393 :013 > campy = Campaign.last
  Campaign Load (0.6ms)  SELECT `campaigns`.* FROM `campaigns` ORDER BY `campaigns`.`id` DESC LIMIT 1
 => #<Campaign id: 3, name: "Stuff", ..., approved_at: nil, approval_requested_at: nil> 
1.9.3p393 :014 > campy.approved_at = Time.now
 => 2013-07-01 00:55:11 +0200 
1.9.3p393 :015 > campy.save
   (0.3ms)  BEGIN
   (0.2ms)  COMMIT
 => true 
1.9.3p393 :016 > Campaign.last.approved_at
  Campaign Load (0.7ms)  SELECT `campaigns`.* FROM `campaigns` ORDER BY `campaigns`.`id` DESC LIMIT 1
 => nil 

我正在尝试将最后一个活动的approved_at 属性的值设置为Time.now,但它仍然为零,即使在我保存它之后也是如此。可以通过 Campaign 模型顶部的 attr_accessor 函数获得approved_at。为什么我不能更改此属性的值?

编辑:

该问题的另一个有趣方面是,当我设置 campy.approved_at 然后显式查找该值时,我得到了正确的值。但是,当我将 campy 视为变量时,Rails 仍将值显示为 nil

1.9.3p393 :027 > campy.approved_at = Time.now
 => 2013-07-01 01:19:05 +0200 
1.9.3p393 :028 > campy.save
   (0.2ms)  BEGIN
   (0.2ms)  COMMIT
 => true 
1.9.3p393 :029 > campy.approved_at
 => 2013-07-01 01:19:05 +0200 
1.9.3p393 :030 > campy
 => #<Campaign id: 3, name: "Stuff", ... , approved_at: nil, approval_requested_at: nil> 
4

1 回答 1

4

这是因为您已approved_at使用attr_accessor. 我建议您对 and 进行一些阅读attr_accessorattr_accessible但在这种情况下,您都不需要。

通过将其指定为虚拟属性,它不会持久化到数据库中。删除attr_accessor线,你不会有任何问题。

解释:

attr_accessor为该模型上的内存属性创建 getter 和 setter 方法。这将优先于ActiveRecord为您的基础数据库属性自动生成的 getter 和 setter 方法,因此当您调用 时save,AR 不会认为您已经更新approved_at,因为实际上您没有更新虚拟属性只要。

attr_accessible用于允许对特定属性进行大规模分配,例如,如果您将值作为属性哈希的一部分传递给createor new

于 2013-06-30T23:23:32.110 回答