在Rails中设置模型的值

时间:2013-06-30 23:01:59

标签: ruby-on-rails activerecord

我在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 

我正在尝试将最后一个Campaign的approved_at属性的值设置为Time.now,但即使我保存它也保持为零。 approved_at通过Campaign模型顶部的attr_accessor函数提供。为什么我不能更改此属性的值?

编辑:

问题的另一个有趣的方面是,当我设置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> 

1 个答案:

答案 0 :(得分:4)

这是因为您已将approved_at创建为attr_accessor的虚拟属性。我建议您对attr_accessorattr_accessible进行一些阅读,但在这种情况下您不需要阅读。

通过将其指定为虚拟属性,它不会持久保存到数据库。删除attr_accessor行,您就不会遇到任何问题。

说明:

attr_accessor为该模型的内存中属性创建getter setter方法。这将优先于ActiveRecord为您的基础数据库属性自动生成的getter和setter方法,因此当您致电save时,AR并不认为您已更新approved_at因为您还没有更新虚拟属性。

attr_accessible用于允许特定属性的质量分配,例如,如果您将值作为属性散列的一部分传递给createnew