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 で動作するようにこれに対処する方法について何か考えはありますか? 明らかに、カスタムのセッターとゲッターを作成できますが、それらは 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 に答える