检测多态关联的关系变化

时间:2017-04-26 20:33:10

标签: ruby-on-rails ruby-on-rails-4 activerecord polymorphic-associations

我有两个通过多态关联链接的模型

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模型,因为我希望这种关注可以重用于其他模型。我很乐意使用关注点在模型中添加一些配置。

跟进问题:这是正确的方法吗?我很惊讶首先调用了更新钩子。也许我应该对创建或删除钩子采取行动呢?我愿意接受建议。

1 个答案:

答案 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

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