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