eragone
eragone

Reputation: 555

update_attributes clearing date fields

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.

Update

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

Answers (1)

RobHeaton
RobHeaton

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

Related Questions