我在表单中将日期作为字符串,并将其作为实际日期字段存储在数据库中。在它上面调用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正在对覆盖它的对象做什么,就像这个必要。任何提示都将不胜感激。
答案 0 :(得分:1)
看起来您的字符串不是ActiveRecord日期字段可以解析为日期的形式。理想情况下,您应该以可以解析的形式(例如Fri, 03 May 2013 10:55:49 UTC +00:00
)获取数据,或者覆盖settor以使其执行以下操作:
def date= value
write_attribute :date, do_stuff_to_the_value(value)
end
在数据到达对象之前操作数据是最好的,但无论如何在设置时将数据写入数据库并不是你想要做的事情。