我很难通过CasinoAmenity获取updated_at列以更新具有__设备的Casino模型。添加便利设施时,赌场的updated_at列会正确更新,但在删除时不会。
这是我的(简化)模型:
casino.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
答案 0 :(得分:9)
首先,您在amenity_casino
模型的两个位置Casino
末尾错过了's'。
应该是这样的:
class Casino < ActiveRecord::Base
has_many :amenity_casinos, :dependent => :destroy
has_many :amenities, :through => :amenity_casinos
end
但是,这不会解决问题。参考this (somewhat old) SO answer,看起来问题是连接表条目被删除,没有被破坏,删除不会触发touch
方法,因此updated_at
不会更新。
要解决此问题,您可以为关联添加:after_remove
选项,并在模型上传递proc
touch
:
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
属性,则必须对{{1}}模型执行相同的操作。
答案 1 :(得分:0)
在我说这个之前我必须注意到我不确定这在Rails 3.2中是否有效,但我确信它在Rails 4 +中有效
现在我知道这已被回答,但仅供将来参考,而不是
> Casino.find(5).amenities = []
您可以使用destroy_all
方法来销毁所有join_model
条记录和touch
关联(如果您在示例中列出了该选项)并执行相应的回调destroy
上的join_model
的{{1}}(示例AmenityCasino
)
> Casino.find(5).amenities.destroy_all