问题
Is there a way to skip updating associations with a :touch association when saving?
Setup:
class School < ActiveRecord::Base
has_many :students
end
class Student < ActiveRecord::Base
belongs_to :school, touch: true
end
I would like to be able to do something like the following where the touch is skipped.
@school = School.create
@student = Student.create(school_id: @school.id)
@student.name = "Trevor"
@student.save # Can I do this without touching the @school record?
Can you do this? Something like @student.save(skip_touch: true) would be fantastic but I haven't found anything like that.
I don't want to use something like update_column because I don't want to skip the AR callbacks.
回答1:
One option that avoids directly monkey patching is to override the method that gets created when you have a relation with a :touch attribute.
Given the setup from the OP:
class Student < ActiveRecord::Base
belongs_to :school, touch: true
attr_accessor :skip_touch
def belongs_to_touch_after_save_or_destroy_for_school
super unless skip_touch
end
after_commit :reset_skip_touch
def reset_skip_touch
skip_touch = false
end
end
@student.skip_touch = true
@student.save # touch will be skipped for this save
This is obviously pretty hacky and depends on really specific internal implementation details in AR.
回答2:
As of Rails v4.1.0.beta1, the proper way to do this would be:
@school = School.create
@student = Student.create(school_id: @school.id)
ActiveRecord::Base.no_touching do
@student.name = "Trevor"
@student.save
end
回答3:
Unfortunately, no. save doesn't provide such option.
Work around this would be to have another time stamp attribute that functions like updated_at but unlike updated_at, it updates only on certain situations for your liking.
来源:https://stackoverflow.com/questions/16221586/skipping-touch-associations-when-saving-an-activerecord-object