8

私は、CasinoAmenity を通じて has_many アメニティを備えたカジノ モデルで updated_at 列を更新するのに苦労しています。カジノの updated_at 列は、設備を追加すると適切に更新されますが、削除すると更新されません。

ここに私の(単純化された)モデルがあります:

カジノ.rb

class Casino < ActiveRecord::Base
  has_many :amenity_casino, :dependent => :destroy
  has_many :amenities, :through => :amenity_casino
end

amenity_casino.rb

class AmenityCasino < ActiveRecord::Base
  belongs_to :casino, :touch => true
  belongs_to :amenity, :touch => true
end

amenity.rb

class Amenity < ActiveRecord::Base
  has_many :amenity_casinos, :dependent => :destroy
  has_many :casinos, :through => :amenity_casinos
end

ではコンソールへ。初期の updated_at 時間を確認しています。

> Casino.find(5).updated_at
=> Wed, 30 Jan 2013 00:30:04 UTC +00:00

カジノにアメニティを追加.

> Casino.find(5).amenities << Amenity.first
=> [#<Amenity id: 1, name: "asdf", weight: "", created_at: "2012-11-10 02:29:14", updated_at: "2013-01-30 01:29:14", description: "asdf">]

関連付けがデータベースに保存されたことを確認する

> Casino.find(5).amenities
=> [#<Amenity id: 1, name: "asdf", weight: "", created_at: "2012-11-10 02:29:14", updated_at: "2013-01-30 01:29:14", description: "asdf">]

予想どおり、そのカジノの updated_at 時刻が変更されていることがわかります。

> Casino.find(5).updated_at
=> Wed, 30 Jan 2013 01:29:14 UTC +00:00

では、そのアメニティをカジノから削除しましょう。

> Casino.find(5).amenities = []
=> []

データベースに正常にヒットすることを確認します

> Casino.find(5).amenities
=> []

それでは、カジノの updated_at 列を確認してみましょう...

> Casino.find(5).updated_at
=> Wed, 30 Jan 2013 01:29:14 UTC +00:00

ご覧のとおり、カジノからアメニティを削除する前と同じです。また、AmenityCasino で before_destroy フィルターを使用してカジノに触れてみましたが、うまくいかなかったようです。

誰かがここで解決策を持っているかどうか聞いてみたいです。問題があれば、ActiveAdmin を使用してすべてを管理しています。

Rails のバージョンは 3.2.11 です

4

2 に答える 2

10

まず、モデルamenity_casinoの2か所の最後に「s」がありません。Casino

このようにする必要があります:

class Casino < ActiveRecord::Base
  has_many :amenity_casinos, :dependent => :destroy
  has_many :amenities, :through => :amenity_casinos
end

ただし、ここでは問題は解決しません。この(やや古い)SOの回答を参照すると、問題は、結合テーブルエントリが削除され、破棄されず、削除によってtouchメソッドがトリガーされないため、updated_at更新されないことであるように見えます。

これを回避するには、関連付けにオプションを追加し、モデル自体を呼び出す:after_removeaを渡すことができます。proctouch

has_many :amenity_casinos, :dependent => :destroy
has_many :amenities, :through => :amenity_casinos,\
         :after_remove => proc { |a| a.touch }

私はこれをテストしました、そしてそれはうまくいくようです:

Casino.find(5).updated_at
#=> Wed, 30 Jan 2013 03:21:29 UTC +00:00
Casino.find(5).amenities << Amenity.first
#=> [#<Amenity id: 1, name: nil, created_at: "2013-01-30 02:48:49", updated_at: "2013-01-30 03:25:23">]
Casino.find(5).amenities
#=> [#<Amenity id: 1, name: nil, created_at: "2013-01-30 02:48:49", updated_at: "2013-01-30 03:25:23">]
Casino.find(5).updated_at
#=> Wed, 30 Jan 2013 03:25:23 UTC +00:00
Casino.find(5).amenities = []
#=> []
Casino.find(5).updated_at
#=> Wed, 30 Jan 2013 03:27:33 UTC +00:00

タイムスタンプが変更されたことがわかります。モデルの属性も更新Amenityする場合は、モデルに対して同じことを行う必要があります。updated_at

于 2013-01-30T02:51:51.167 に答える