Reputation: 555
I'm taking in a date as a string in my form, and storing it as an actual date field in the database. When calling update_attributes on it, it seems Rails is clearing the value at some point before I can access it - even if I set it manually, it doesn't actually get set.
Table:
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
Model:
class MyObject < ActiveRecord::Base
attr_accessible :date
end
Console:
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
Now, when I try to use update_attributes, I figure I might be able to modify the value in the before_validation callback, but the value isn't even available there:
Add a callback to the class:
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
Any thoughts on how I can deal with this so it works with update_attributes? Obviously, I could write custom setters and getters, but those don't get called with update_attributes.
I tried changing the column to "thingdate", with the identical results.
For now, I've worked around the issue as follows:
class MyObject < ActiveRecord::Base
attr_writer :date
attr_accessible :date
def date= value
update_column :date, value
end
end
For whatever reason, this allows the value - really, any value that looks like it could be a date (presumably the limitation is on postgres) - to be saved as well as stored in the object. I'm not exactly sure what Rails is doing to the object that makes overwriting it like this necessary. Any hints would be greatly appreciated.
Upvotes: 2
Views: 627
Reputation: 1390
It looks like your string isn't in a form that ActiveRecord date fields can parse into a date. You should ideally get your data in a form that it can parse (such as Fri, 03 May 2013 10:55:49 UTC +00:00
), or alternatively overwrite the settor so that it does something like:
def date= value
write_attribute :date, do_stuff_to_the_value(value)
end
Manipulating the data before it hits the object would be best, but in any case writing it to the database on setting is not something you want to do.
Upvotes: 1