我将日期作为字符串输入表单,并将其作为实际日期字段存储在数据库中。当对它调用update_attributes时,Rails似乎在我访问它之前的某个时刻清除了这个值——即使我手动设置了它,它实际上也没有被设置。
表:
Table "public.my_objects"
Column | Type | Modifiers
------------+-----------------------------+-----------------------------------------------------------
id | integer | not null default nextval('my_objects_id_seq'::regclass)
date | date |
created_at | timestamp without time zone | not null
updated_at | timestamp without time zone | not null
型号:
class MyObject < ActiveRecord::Base
attr_accessible :date
end
控制台:
1.9.3p327 :001 > my_object = MyObject.new
=> #<MyObject id: nil, date: nil, created_at: nil, updated_at: nil>
1.9.3p327 :002 > my_object.date = "12-15-2012"
=> "12-15-2012"
1.9.3p327 :003 > my_object.date
=> nil
现在,当我尝试使用update_attributes时,我想我可能能够修改before_validation回调中的值,但该值在那里甚至不可用:
向类添加回调:
class MyObject < ActiveRecord::Base
...
before_validation :print_date
def print_date
puts "Date value: #{self.date}"
puts "Date value: #{date}"
puts "before validation"
end
end
1.9.3p327 :001 > my_object = MyObject.create
(0.2ms) BEGIN
Date value:
Date value:
before validation
SQL (72.0ms) INSERT INTO "my_objects" ("created_at", "date", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["created_at", Sun, 09 Dec 2012 20:56:04 UTC +00:00], ["date", nil], ["updated_at", Sun, 09 Dec 2012 20:56:04 UTC +00:00]]
(0.7ms) COMMIT
=> #<MyObject id: 15, date: nil, created_at: "2012-12-09 20:56:04", updated_at: "2012-12-09 20:56:04">
1.9.3p327 :002 > my_object.update_attributes :date => "12-15-2012"
(0.1ms) BEGIN
Date value:
Date value:
before validation
(0.1ms) COMMIT
=> true
关于如何处理这个问题,让它与update_attributes一起工作,有什么想法吗?显然,我可以编写自定义的setter和getter,但它们不会用update_attributes调用。
更新
我尝试将该列更改为"thingdate",结果完全相同。
目前,我已经围绕这个问题进行了如下工作:
class MyObject < ActiveRecord::Base
attr_writer :date
attr_accessible :date
def date= value
update_column :date, value
end
end
无论出于何种原因,这都允许将值——实际上,任何看起来可能是日期的值(可能限制在postgres上)——保存并存储在对象中。我不太确定Rails对这个对象做了什么,所以有必要覆盖它。如有任何提示,我们将不胜感激。
看起来字符串的形式不是ActiveRecord日期字段可以解析为日期的形式。理想情况下,您应该以一种可以解析的形式(如Fri, 03 May 2013 10:55:49 UTC +00:00
)获取数据,或者重写设置,使其执行以下操作:
def date= value
write_attribute :date, do_stuff_to_the_value(value)
end
在数据到达对象之前操作数据是最好的,但在任何情况下,在设置时将其写入数据库都不是你想做的事情