0

Railsで奇妙な問題が発生しています。Rails のモデルにフィールドの値を設定したいのですが、Rails コンソールでもできません。観察:

1.9.3p393 :008 > campy = Campaign.last
  Campaign Load (0.8ms)  SELECT `campaigns`.* FROM `campaigns` ORDER BY `campaigns`.`id` DESC LIMIT 1
 => #<Campaign id: 3, name: "Stuff", ..., approved_at: nil, approval_requested_at: nil> 
1.9.3p393 :009 > campy.approved_at = Time.now
 => 2013-07-01 00:54:38 +0200 
1.9.3p393 :010 > campy.save
   (0.2ms)  BEGIN
   (0.2ms)  COMMIT
 => true 
1.9.3p393 :011 > campy.approved_at
 => 2013-07-01 00:54:38 +0200 
1.9.3p393 :012 > Campaign.last.approved_at
  Campaign Load (0.7ms)  SELECT `campaigns`.* FROM `campaigns` ORDER BY `campaigns`.`id` DESC LIMIT 1
 => nil 
1.9.3p393 :013 > campy = Campaign.last
  Campaign Load (0.6ms)  SELECT `campaigns`.* FROM `campaigns` ORDER BY `campaigns`.`id` DESC LIMIT 1
 => #<Campaign id: 3, name: "Stuff", ..., approved_at: nil, approval_requested_at: nil> 
1.9.3p393 :014 > campy.approved_at = Time.now
 => 2013-07-01 00:55:11 +0200 
1.9.3p393 :015 > campy.save
   (0.3ms)  BEGIN
   (0.2ms)  COMMIT
 => true 
1.9.3p393 :016 > Campaign.last.approved_at
  Campaign Load (0.7ms)  SELECT `campaigns`.* FROM `campaigns` ORDER BY `campaigns`.`id` DESC LIMIT 1
 => nil 

前回のキャンペーンの approval_at 属性の値を Time.now に設定しようとしていますが、保存した後も nil のままです。承認された_at は、キャンペーンのモデルの上部にある attr_accessor 関数を介して利用可能になります。この属性の値を変更できないのはなぜですか?

編集:

この問題のもう 1 つの興味深い点は、campy.approved_at を設定してから値を明示的に検索すると、正しい値が得られることです。ただし、campy を変数として見ると、Rails はまだ値を nil と表示します。

1.9.3p393 :027 > campy.approved_at = Time.now
 => 2013-07-01 01:19:05 +0200 
1.9.3p393 :028 > campy.save
   (0.2ms)  BEGIN
   (0.2ms)  COMMIT
 => true 
1.9.3p393 :029 > campy.approved_at
 => 2013-07-01 01:19:05 +0200 
1.9.3p393 :030 > campy
 => #<Campaign id: 3, name: "Stuff", ... , approved_at: nil, approval_requested_at: nil> 
4

1 に答える 1

4

これはapproved_at、 で仮想属性として作成したためですattr_accessorattr_accessorとを読むことをお勧めしますattr_accessibleが、この場合はどちらも必要ありません。

仮想属性として指定すると、データベースに永続化されません。行を削除するattr_accessorと、問題はなくなります。

説明:

attr_accessorそのモデルのメモリ内属性の getter メソッドと setter メソッドを作成します。これは、基礎となるデータベース属性に対して自動的に生成される getter および setter メソッドよりも優先されるActiveRecordため、 を呼び出すとsave、AR は更新されたとは見なしません。approved_at実際には仮想属性を更新していないためです。それだけ。

attr_accessiblecreate属性のハッシュの一部として値をまたはに渡す場合など、特定の属性の一括割り当てを可能にするために使用されますnew

于 2013-06-30T23:23:32.110 に答える