0

检测关系的变化我有2个模型是通过一个多态关联对多态关联

class MyModel < ActiveRecord::Base 
    has_many :taggings, :as => :taggable 
    has_many :tags, :through => :taggings 

    def tags=(ids) 
    self.tags.delete_all 
    self.tags << Tag.where(id: ids) 
    end 
end 

class Tagging < ActiveRecord::Base 
    include PublishablePolymorphicRelationship 
    belongs_to :tag 
    belongs_to :taggable, :polymorphic => true 
end 


class Tag < ActiveRecord::Base 
    has_many :taggings 
    has_many :my_models, :through => :taggings, :source => :taggable, :source_type => 'MyModel' 
end 

tag1 = Tag.create!(...) 
tag2 = Tag.create!(...) 
my_model = MyModel.create!(...) 

my_model.update!(tags: [tag1.id]) 

我创建一个实现after_update挂钩,这样我可以发布一个消息队列变化的关注挂钩

但是,当调用挂钩时,更改哈希值为空。以及为关系

module PublishablePolymorphicRelationship 
    extend ActiveSupport::Concern 
    included do 
    after_update :publish_update 

    def publish_update 
     model = self.taggable 
     puts model.changes 
     puts self.changes 
     ... # do some message queue publish code 
    end 
    end 

末 这将返回

{} 
{} 

有没有方法可以让我赶上了多态关联的变化。 理想情况下,我不会直接参考关注的tags模型,因为我希望此关注可以重用于其他模型。尽管如此,我愿意在模型中添加一些配置。

跟进问题:这是正确的方法吗?我很惊讶,更新挂钩首先被调用。也许我应该在创建或删除挂钩上采取行动?我乐于接受建议。

+0

开始摆脱hacky'MyModel#tags ='setter。通过使用rails for'has_many'关联创建的'tags_ids ='setter,已经有了更好的构建方法。它也可以使用复选框帮助程序。 – max

+0

同样为了您的工作需要,您需要将'after_update:publish_update'放在'included do ... end'块中。回调和关联在模型的类定义中定义。但我不明白为什么你使用一个问题,因为它似乎不是很可重用。 – max

+0

为了简化示例,我在实践中用'self.taggable'硬编码模型,我使用类方法来设置多态关系密钥,并使用'self.send(_polymorphic_key)'这有意义吗?您认为这会提高可重用性吗? – QuantumLicht

回答

1

它不会按照您的想法工作 - taggings只是一个连接模型。只有在向项目添加/删除标签时,才会真正插入/删除行。发生这种情况时,关联的任何一端都没有变化。

因此,除非您实际手动更新标记以及关联的任一末端,否则publish_update将返回空的散列。

如果你想创建一个通知一个可重用的组件,您创建一个M2M关联时/摧毁你会做它像这样:

module Trackable 

    included do 
    after_create :publish_create! 
    after_destroy :publish_destroy! 
    end 

    def publish_create! 
    puts "#{ taxonomy.name } was added to #{item_name.singular} #{ item.id }" 
    end 

    def publish_destroy! 
    puts "#{ taxonomy.name } was removed from #{item_name.singular} #{ item.id }" 
    end 

    def taxonomy_name 
    @taxonomy_name || = taxonomy.class.model_name 
    end 

    def item_name 
    @item_name || = item.class.model_name 
    end 
end 

class Tagging < ActiveRecord::Base 
    include PublishablePolymorphicRelationship 
    belongs_to :tag 
    belongs_to :taggable, polymorphic: true 

    alias_attribute :item, :taggable 
    alias_attribute :taxonomy, :tag 
end 

class Categorization < ActiveRecord::Base 
    include PublishablePolymorphicRelationship 
    belongs_to :category 
    belongs_to :item, polymorphic: true 

    alias_attribute :item, :taggable 
    alias_attribute :taxonomy, :tag 
end 

否则,你需要跟踪回调应用到实际的课程你有兴趣的变化。

+1

你可能想看看如何建立https://github.com/chaps-io/public_activity – max