许多与多态关联不能在两个方向工作
问题描述:
我正在实施系统,使用户能够遵循“可跟踪”(在我的情况下,这些可能是一个事件,地点或其他用户)。许多与多态关联不能在两个方向工作
我的想法:
关注模型认为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..
所有上述返回零。
我应该如何建立关系,使其在两个方向上工作?
另外,我想听听一些关于如何改善这个想法的评论,这是我第一次玩更复杂的实时信息。 预先感谢您。
答
让我们与用户模型,开始了其最棘手:
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
快速思考:你确定你没有看到'event1.follows'的陈旧缓存吗?当你尝试'event1.follows(true)'时会发生什么? (这里的'true'告诉ActiveRecord重新加载关联,而不是使用它的缓存,如果有的话) –
输出:# –
Wojciech
event1.follows.to_sql怎么样? –