Touch an ActiveRecord - timestamps


#1

When I update an ActiveRecord, i would like to “touch” one of the
related objects, that the updated record belongs_to, in order to update
the timestamps on the parent record, although i don’t want to change any
of the data in the parent. Whats the accepted way to do this?


#2

just calling save on the parent association works in my testing, e.g.
some_child.some_parent.save

On Nov 13, 10:08 am, David W. <rails-mailing-l…@andreas-


#3

Jeff Emminger wrote:

just calling save on the parent association works in my testing, e.g.
some_child.some_parent.save

On Nov 13, 10:08�am, David W. <rails-mailing-l…@andreas-

That was the first thing i tried :(. I have rails 2.1.1.


#4

working for me in 2.1.2

parent class

class Team < ActiveRecord::Base
has_many :games
end

child class

class Game < ActiveRecord::Base
belongs_to :team
end

unit test

require ‘test_helper’
class GameTest < ActiveSupport::TestCase

def test_updates_parent_timestamps
team = Team.create(:name => ‘Team 1’)
game = Game.create
team.games << game

team.save

assert team.valid?
assert game.valid?

old_date = team.updated_at
game.team.save

assert_not_equal old_date, team.reload.updated_at

end

end

On Nov 13, 3:40 pm, David W. removed_email_address@domain.invalid


#5

I recommend an observer to do this, and I also recommend using a
different
column other than updated_at. I use last_modified_at to store the date
that
any part was changed, and reserve updated_at for tracking when the
individual pieces are changed.

Something like this would work, although this is done from memory.

class UpdateObserver < ActiveRecord::Obeserver
observe :project, :task, :note, :attachment

def after_save(record)
if record.is_a? Project
p = record
else
p = record.project
end
p.last_modified_at = Time.now
p.save!
end

def after_destroy(record)
unless record.is_a? Project
p = record.project
p.last_modified_at = Time.now
p.save!
end
end
end

On Thu, Nov 13, 2008 at 7:12 PM, Frederick C. <


#6

On Nov 13, 10:18 pm, jemminger removed_email_address@domain.invalid wrote:

end
team.save

assert team.valid?
assert game.valid?

old_date = team.updated_at
game.team.save

assert_not_equal old_date, team.reload.updated_at

end

I expect that passes only because old_date was basically set to
Time.now (so has a fractional second component), whereas
team.reload.updated_at is fetched from the database, so the fractional
portion of the second is lost.
In rails 2.1 game.team.save is a no-op because only changed attributes
are saved (and here none are changed). You can force a save by
modifying any attribute or calling one of the _will_change! methods ie

def touch
updated_at_will_change!
save
end

Fred