2015-04-21 47 views
0

型号:验证has_many关联的破坏?

class Factory < ActiveRecord::Base 
    has_many :factory_workers 
    has_many :workers, through: :factory_workers 
end 

class FactoryWorkers < ActiveRecord::Base 
    belongs_to :factory 
    belongs_to :worker 

    before_destroy :union_approves? 

    private 

    def union_approves? 
    errors.add(:proletariat, "is never destroyed!") 

    false 
    end 
end 

class Worker < ActiveRecord::Base 
    has_many :factory_workers 
    has_many :factorys, through: :factory_workers 
end 

如果我尝试更新一个工厂的通过工厂工人的名单,并导致一些FactoryWorker协会的破坏,我希望before_destroy钩被调用,但这似乎没有不是这样的。

Factory.create(name: 'communist paradise', worker_ids: [1, 2]) 

Factory.find_by(name: 'commnist paradise').update(worker_ids: [1]) 
# before_destroy hook is not called, proletariat must riot! 

更新记录协会的时候我怎么能保证before_destory钩子叫什么名字?

+0

before_destory之前摧毁方法调用。你不是指before_update吗? – Michal

+0

@Michal我想确保在“through”模型FactoryWorkers上调用before_destroy方法,如果更新父模型Factory,导致FactoryWorker记录被销毁。看看我的帖子底部的例子。请注意,使用比以前更少的worker_id调用.update会导致FactoryWorker记录被破坏,但ActiveRecord似乎没有调用before_destroy钩子(可能是因为它没有实例化FactoryWorker实例)。 – kjb

+0

你真的不应该像在你的例子中那样对对象ID做任何引用。 Rails有非常复杂的方法来与关联进行交互,以避免你需要混淆对象的ID。 – Jon

回答

1

找到我需要的东西:ActiveRecord的提供了一个协会方法before_remove,所以我只需要rejigger如下:

class Factory < ActiveRecord::Base 
    has_and_belongs_to_many :workers, before_remove: :union_approves? 

    private 

    def union_approves? 
    ... 
    end 
end