检测多态关联的关系变化

Detect relation changes on polymorphic association

我有 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

结束 这将 return

{}
{}

有什么方法可以捕获多态关联的变化。 理想情况下,我不会在关注点中直接引用 tags 模型,因为我希望此关注点可重用于其他模型。不过,我愿意使用关注点在模型中添加一些配置。

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

它永远不会像您想象的那样工作 - taggings 只是一个连接模型。当您 add/remove 标记一个项目时,行实际上只是 inserted/deleted 间接的。当这种情况发生时,关联的两端都没有变化。

因此,除非您实际手动更新标记和关联的任一端,否则 publish_update 将 return en 空哈希。

如果您想创建一个可重用的组件,当 m2m 关联 created/destroyed 时通知您,您可以这样做:

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

否则,您需要将跟踪回调应用到您感兴趣的实际 类 更改。