2

我在表单中将日期作为字符串输入,并将其作为实际日期字段存储在数据库中。在对其调用 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 对对象做了什么使得像这样覆盖它是必要的。任何提示将不胜感激。

4

1 回答 1

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

在数据到达对象之前对其进行操作是最好的,但无论如何在设置时将其写入数据库并不是您想要做的事情。

于 2013-05-03T13:37:29.683 回答