Sometimes I need to update fields in record without updating its timestamp (updated_at). To acomplish this, after modifying the object I call object.updated_at_will_change! and then object.save which causes updated_at to remain the same in database.
But in certain circumstances it is not possible.
In one-to-one association scenario when one side has :autosave => true and other has :touch => true accessing association then saving record causes updated_at to be overwritten with current timestamp.
Assuming we have these two models:
class Firm < ActiveRecord::Base
has_one :user, :autosave => true
class User < ActiveRecord::Base
belongs_to :firm, :touch => true
# Create firm and user
f = Firm.new
# Set updated_at and save
time = Time.mktime 1, 1, 1
f = find f.id
f.updated_at = time # in my code I use f.updated_at_will_change! but here I want timestamp difference to be more visible
# Compare updated at with value with value which was set earlier
f.reload.updated_at == time
returns false. It means f.updated_at was set to current time, not to user specified value. In logs, two consecutive updates can be seen.
Now try to execute above code, but without accessing user (comment out f.user line). Observe that updated_at was set correctly.
Now uncomment f.user line back and remove :touch => true. Once again, updated_at is being set correctly.
Now restore :touch => true and remove :autosave => true. This time updated_at is also correct.
So the bug can be observed if every three of the conditions are met:
I don't know what the expected bahaviour should be. But I think that accessing association without modifing it shouldn't update main object timestamp.
Tested on Rails 3.1.0 and 3.0.5.
Do you test code to verify this is broken?
I don't have automated tests -- only manual test pasted in issue text.
Does this still happen on 3.2 and/or master?
Maybe it is very similar with my experience. When is touch defined in association within has_one, updated_at is always changed to current timestamp even when child object is not changed. If is association defined as has_many this behaviour is correct, and updated_at is not changed.
Have two models
class Place < ActiveRecord::Base
has_one :location, inverse_of: :place, dependent: :destroy
class Location < ActiveRecord::Base
belongs_to :place, inverse_of: :location, touch: true
When is Place opened to edit, no changes in Place nor Location. Saved to update -> updated_at in Place is always changed.
If is association changed to has_many :locations .... And do same event: Open place, no changes, click on update. updated_at is not changed as i exepted.
has_many :locations ....
I don't find any documentation about changes between touch behaviour in has_many and has_one.
Tested with rails_admin
Please submit a gist following the templates metoned at https://gist.github.com/neerajdotname/5187216 so that I could look into it.
This should honestly just be closed.
Yes, the more I look at this, the more it feels like expected behavior. touch + autosave will update updated_at, that's kind of the whole point of touch.
If you can provide a concise example (via the template @neerajdotname suggested) demonstrating why there's an actual bug somewhere in Rails, we can re-open. But for now, I think this is because you're fighting expected behavior.