许多与多态关联不能在两个方向工作

问题描述:

我正在实施系统,使用户能够遵循“可跟踪”(在我的情况下,这些可能是一个事件,地点或其他用户)。许多与多态关联不能在两个方向工作

我的想法:

关注模型认为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怎么样? –

让我们与用户模型,开始了其最棘手:

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