我在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>
答案 0 :(得分:4)
这是因为您已将approved_at
创建为attr_accessor
的虚拟属性。我建议您对attr_accessor
和attr_accessible
进行一些阅读,但在这种情况下您不需要阅读。
通过将其指定为虚拟属性,它不会持久保存到数据库。删除attr_accessor
行,您就不会遇到任何问题。
说明:
attr_accessor
为该模型的内存中属性创建getter setter方法。这将优先于ActiveRecord
为您的基础数据库属性自动生成的getter和setter方法,因此当您致电save
时,AR并不认为您已更新approved_at
因为您还没有更新虚拟属性。
attr_accessible
用于允许特定属性的质量分配,例如,如果您将值作为属性散列的一部分传递给create
或new
。