I'm having a hard time getting the updated_at column to update on a Casino model that has_many Amenities through CasinoAmenity. The casino's updated_at column gets updated properly when adding amenities, but not when removing them.
Here's my (simplified) models:
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
Now to the console. Checking the initial updated_at time.
> Casino.find(5).updated_at
=> Wed, 30 Jan 2013 00:30:04 UTC +00:00
Adding an amenity to the casino.
> 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">]
Confirming the association was saved to the database
> 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">]
We can see that the updated_at time for that casino has changed, as expected.
> Casino.find(5).updated_at
=> Wed, 30 Jan 2013 01:29:14 UTC +00:00
Now let's remove that amenity from the casino.
> Casino.find(5).amenities = []
=> []
Now making sure it hit the database fine
> Casino.find(5).amenities
=> []
Now let's check the updated_at column for the casino...
> Casino.find(5).updated_at
=> Wed, 30 Jan 2013 01:29:14 UTC +00:00
As you can see, it's the same as before we removed the amenity from the casino. I've also tried a before_destroy filter on AmenityCasino to touch the casino, but that didn't seem to do the trick.
I'd love to hear if anyone has any solutions here. If it matters, I'm using ActiveAdmin to manage everything.
Rails version is 3.2.11
First, you're missing an 's' at the end of amenity_casino
in two places in your Casino
model.
Should be like this:
class Casino < ActiveRecord::Base
has_many :amenity_casinos, :dependent => :destroy
has_many :amenities, :through => :amenity_casinos
end
That won't solve the problem here, though. Referring to this (somewhat old) SO answer, it looks like the problem is that join table entries are deleted, not destroyed, and deletes don't trigger the touch
method, thus updated_at
is not updated.
To get around that, you can add an :after_remove
option to your association and pass a proc
which calls touch
on the model itself:
has_many :amenity_casinos, :dependent => :destroy
has_many :amenities, :through => :amenity_casinos,\
:after_remove => proc { |a| a.touch }
I've tested this and it seems to work:
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
You can see that the timestamp has changed. You'll have to do the same thing for your Amenity
model if you want to have the updated_at
attribute updated on that one as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With