1

我正在實施系統,使用戶能夠遵循「可跟蹤」(在我的情況下,這些可能是一個事件,地點或其他用戶)。許多與多態關聯不能在兩個方向工作

我的想法:

關注模型認爲user_ID的,隨動型和followale_id(連接表)

class Follow < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :followable, polymorphic: true 
end 

事件

class Event < ActiveRecord::Base  
    has_many :follows, as: :followable 
    has_many :users, through: :follows 
end 

廣場

class Place < ActiveRecord::Base 
    has_many :follows, as: :followable 
    has_many :users, through: :follows  
end 

用戶

class User < ActiveRecord::Base 
    has_many :follows 
    has_many :events, through: :follows, source: :followable, source_type: "Event" 
    has_many :places, through: :follows, source: :followable, source_type: "Place" 
    has_many :users, through: :follows, source: :followable, source_type: "User" 
end 

的問題是,維吾爾只能在一個方向,我可以這樣做:

user.follows.create(followable:event1) #follow event1 
user.follows.create(followable:place1) #follow place1 
user.follows.create(followable:user1) #follow user1 
user.follows # displays all following relations user has established 

但是,我不能這樣做

event1.follows #return follow objects(some user - event1 pairs) 
event1.users #return all of the users that follow this event 
user1.users #return all of the users that user1 follows, the most confusing part.. 

所有上述返回零。

我應該如何建立關係,使其在兩個方向上工作?
另外,我想聽聽一些關於如何改善這個想法的評論,這是我第一次玩更復雜的實時信息。 預先感謝您。

+0

快速思考:你確定你沒有看到'event1.follows'的陳舊緩存嗎?當你嘗試'event1.follows(true)'時會發生什麼? (這裏的'true'告訴ActiveRecord重新加載關聯,而不是使用它的緩存,如果有的話) –

+0

輸出:# Wojciech

+0

event1.follows.to_sql怎麼樣? –

回答

1

讓我們與用戶模型,開始了其最棘手:

class User < ActiveRecord::Base 
    has_many :follows, source: :user 
    has_many :follows_as_fallowable, 
        class_name: 'Follow', 
        as: :followable 

    has_many :followers, through: :follows_as_fallowable, 
         source: :user 

    # other users the user is following      
    has_many :followed_users, through: :follows, 
          source: :followable, 
          source_type: 'User' 
end 

需要注意的是,我們需要follows兩種不同的關係,由於該用戶可以在任一列取決於用戶是否追隨者或被追隨的對象。

現在,我們可以做一個簡單的測試,以檢查是否關係是正確設置:

joe = User.create(name: 'Joe') 
jill = User.create(name: 'Jill') 
joe.followers << jill 
jill.followed_users.include?(joe) # true 
joe.followers.include?(jill) # true 

然後,爲了建立一個用戶和一個隨動模型之間的雙向關係,你會怎麼做:

class Event < ActiveRecord::Base 
    has_many :follows, as: :followable 
    has_many :followers, through: :follows, 
         source: :user 
end 

class User < ActiveRecord::Base 
    # ... 
    has_many :followed_events, through: :follows, 
          source: :followable, 
          source_type: 'Event' 
end 

所述遵循的模型(事件)的關係幾乎在每一個模型一樣的,所以你可以很容易地將它解壓到重用模塊:

# app/models/concerns/followable.rb 
module Followable 
    extend ActiveSupport::Concern 

    included do 
    has_many :follows, as: :followable 
    has_many :followers, through: :follows, 
         source: :user 
    end 
end 

class Event < ActiceRecord::Base 
    include Followable 
end 

class Place < ActiceRecord::Base 
    include Followable 
end 
+0

非常感謝,它完美地工作,但有一個理解一件事情的問題: 'has_many:追隨者,通過::follow_as_fallowable, 來源::用戶' 如何軌道知道從哪個表中選擇?它不基於關聯名稱進行推導,它不從class_name參數中獲取它。那麼它如何知道它應該返回用戶記錄? – Wojciech

+0

'source::user'告訴它在Follow上獲得'_belongs_to:user'關係,它不是多態的。 – max