我正在实施一个系统,使用户能够遵循"可跟随"(在我的情况下,这些可能是一个事件,地点或其他用户)。
我的想法:
关注模型包含user_id,followable类型和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 :(得分: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