我有两个通过多态关联链接的模型
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 :(得分: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
否则,您需要将跟踪回调应用于您对更改感兴趣的实际类。