views:

44

answers:

1

I've got pretty much the same problem as this guy: http://www.ruby-forum.com/topic/197440.

I'm trying to touch a column (:touched_at) without having it auto-update :updated_at, but watching the SQL queries, it always updates both to the current time.

I thought it might be something to do with the particular model I was using it on, so I tried a couple different ones with the same result.

Does anyone know what might be causing it to always set :updated_at when touching a different column? touch uses write_attribute internally, so it shouldn't be doing this.

Edit:

Some clarification... the Rails 2.3.5 docs for touch state that "If an attribute name is passed, that attribute is used for the touch instead of the updated_at/on attributes." But mine isn't acting that way. Perhaps it's a case of the docs having drifted away from the actual state of the code?

+3  A: 

You pretty much want to write custom SQL:

def touch!
  self.class.update_all({:touched_at => Time.now.utc}, {:id => self.id})
end

This will generate this SQL:

UPDATE posts SET touched_at = '2010-01-01 00:00:00.0000' WHERE id = 1

which is what you're after. If you call #save, this will end up calling #create_with_timestamps or #update_with_timestamps, and these are what update the updated_on/updated_at/created_on/created_at columns.

By the way, the source for #touch says it all.

François Beausoleil
This seems to be the only way. Looks like the Rails 2.3.5 docs are just wrong. I'd add to you answer that I could put the `touch!` method in a callback on the model to finish replicating the functionality of ActiveRecord `belongs_to`'s `:touch => :column` (which I think uses `before_save` and `before_destroy`, but I'd have to check the source).
tfe