2013-04-25 55 views
7

有没有办法来跳过更新协会与:touch协会保存时?跳绳:触摸协会保存一个ActiveRecord对象时

设置:

class School < ActiveRecord::Base 
    has_many :students 
end 

class Student < ActiveRecord::Base 
    belongs_to :school, touch: true 
end 

我想能够做到像下面这样在触摸被跳过。

@school = School.create 
@student = Student.create(school_id: @school.id) 
@student.name = "Trevor" 
@student.save # Can I do this without touching the @school record? 

你能做到吗?类似@student.save(skip_touch: true)会很棒,但我还没有找到类似的东西。

我不想使用像update_column,因为我不想跳过AR回调。

+1

所以你平时想触摸,但有时跳过触摸? – AlexBrand 2013-04-25 18:12:58

+0

确实如此。基本上我有一种情况,我正在更新所有触摸相同关系的多个模型。我想在这种情况下避免碰触。 – 2013-04-25 18:14:06

回答

2

一种选择是重写,当你有一个:touch属性的关系时生成的方法。

鉴于从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 

这显然是相当哈克和依赖于真正具体的内部实现细节AR。

+0

“belongs_to_touch_after_save_or_destroy_for_school”的定义在哪里? – 2014-10-20 03:35:48

+0

它由'belongs_to'函数定义。取决于你的Rails版本,你可以在'activerecord-3.2.19/lib/active_record/associations/builder/belongs_to.rb:51'这样的地方找到它。 – 2014-10-20 16:29:07

1

不幸的是,没有。 save不提供这样的选项。

解决此问题的方法是使用另一个时间戳属性,其功能类似于updated_at,但与updated_at不同,它仅在某些情况下根据自己的喜好更新。直接避免猴子修补

0

铁轨v4.1.0.beta1的,这样做的正确方法应该是:

@school = School.create 
@student = Student.create(school_id: @school.id) 

ActiveRecord::Base.no_touching do 
    @student.name = "Trevor" 
    @student.save 
end