具有多态关联的多对多在两个方向上都不起作用
Many to many with polymorphic association doesn't work in both directions
我正在实施使用户能够关注 "followable"(在我的情况下,这些可能是事件、地点或其他用户)的系统。
我的想法:
Follow 模型包含 user_id、可关注类型和 followale_id(加入 table)
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..
以上全部return无。
我应该如何建立关系以使其双向工作?
另外,我想听听一些关于如何改进这个想法的评论,因为这是我第一次玩更复杂的 realtions。
提前谢谢你。
让我们从最棘手的用户模型开始:
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
我正在实施使用户能够关注 "followable"(在我的情况下,这些可能是事件、地点或其他用户)的系统。
我的想法:
Follow 模型包含 user_id、可关注类型和 followale_id(加入 table)
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..
以上全部return无。
我应该如何建立关系以使其双向工作?
另外,我想听听一些关于如何改进这个想法的评论,因为这是我第一次玩更复杂的 realtions。
提前谢谢你。
让我们从最棘手的用户模型开始:
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