Rails5 如何使用 ActiveRecord 关系对象构建提要
Rails5 How can I build a feed with ActiveRecord Relation objects
我想用微博建立一个提要:
首先我从我的关注者visible_for 'following'
收集所有微博
following_ids_subselect = "SELECT followed_id FROM relationships
WHERE follower_id = :user_id"
following_feed = Micropost.where("visible_for = 'following'
AND user_id IN (#{following_ids_subselect})", user_id: id)
然后我从我的关注者(和状态 "contact")收集所有微博 visible_for 'contact'
contacts_ids_subselect = "SELECT followed_id FROM relationships
WHERE follower_id = :user_id
AND status = 'contact'"
contacts_feed = Micropost.where("visible_for = 'contacts'
AND user_id IN (#{contacts_ids_subselect})", user_id: id)
有什么方法可以让 following_feed
和 contacts_feed
在一起吗?我可以写:
@feed_items = global_feed.paginate(page: params[:page])
换句话说:
global_feed
应包含当前用户关注 visible_for 'followers'
的所有微博
+
当前用户关注status 'contact'
和visible_for 'contacts'
的所有微博
更新:
关系
class Relationship < ApplicationRecord
# Table name: relationships
#
# id :integer(4) not null, primary key
# follower_id :integer(4)
# followed_id :integer(4)
# status :string
belongs_to :follower, class_name: "User"
belongs_to :followed, class_name: "User"
end
用户
class User < ApplicationRecord
has_many :active_relationships, class_name: "Relationship",
foreign_key: "follower_id",
dependent: :destroy
has_many :following, through: :active_relationships, source: :followed
has_many :passive_relationships, class_name: "Relationship",
foreign_key: "followed_id",
dependent: :destroy
has_many :followers, through: :passive_relationships, source: :follower
(..)
end
微博
class Micropost < ApplicationRecord
#
# Table name: microposts
#
# id :integer(4) not null, primary key
# user_id :integer(4)
# content :string
# visible_for :string
belongs_to :user
default_scope -> { order('created_at DESC') }
end
#paginate
是一种仅适用于 ActiveRecord 关系的方法。这意味着您将需要 select 在一次查询中获得所需的数据。
因此,如果我正确阅读了您的样本,您希望当前用户关注的用户的所有 Micropost
对 contacts
或 following
可见。
您可以像这样 select 在一个查询中使用它们
following_user_ids = user.following.pluck(:id)
contact_user_ids = Relationship.where(status: "contact", follower_id: user.id).pluck(:follower_id)
Microposts.where("(visible_for = 'followers' and user_id in (?)) OR (visible_for = "contacts" and user_id in (?)"), following_user_ids, contact_user_ids))
我想用微博建立一个提要:
首先我从我的关注者visible_for 'following'
following_ids_subselect = "SELECT followed_id FROM relationships
WHERE follower_id = :user_id"
following_feed = Micropost.where("visible_for = 'following'
AND user_id IN (#{following_ids_subselect})", user_id: id)
然后我从我的关注者(和状态 "contact")收集所有微博 visible_for 'contact'
contacts_ids_subselect = "SELECT followed_id FROM relationships
WHERE follower_id = :user_id
AND status = 'contact'"
contacts_feed = Micropost.where("visible_for = 'contacts'
AND user_id IN (#{contacts_ids_subselect})", user_id: id)
有什么方法可以让 following_feed
和 contacts_feed
在一起吗?我可以写:
@feed_items = global_feed.paginate(page: params[:page])
换句话说:
global_feed
应包含当前用户关注 visible_for 'followers'
的所有微博
+
当前用户关注status 'contact'
和visible_for 'contacts'
更新:
关系
class Relationship < ApplicationRecord
# Table name: relationships
#
# id :integer(4) not null, primary key
# follower_id :integer(4)
# followed_id :integer(4)
# status :string
belongs_to :follower, class_name: "User"
belongs_to :followed, class_name: "User"
end
用户
class User < ApplicationRecord
has_many :active_relationships, class_name: "Relationship",
foreign_key: "follower_id",
dependent: :destroy
has_many :following, through: :active_relationships, source: :followed
has_many :passive_relationships, class_name: "Relationship",
foreign_key: "followed_id",
dependent: :destroy
has_many :followers, through: :passive_relationships, source: :follower
(..)
end
微博
class Micropost < ApplicationRecord
#
# Table name: microposts
#
# id :integer(4) not null, primary key
# user_id :integer(4)
# content :string
# visible_for :string
belongs_to :user
default_scope -> { order('created_at DESC') }
end
#paginate
是一种仅适用于 ActiveRecord 关系的方法。这意味着您将需要 select 在一次查询中获得所需的数据。
因此,如果我正确阅读了您的样本,您希望当前用户关注的用户的所有 Micropost
对 contacts
或 following
可见。
您可以像这样 select 在一个查询中使用它们
following_user_ids = user.following.pluck(:id)
contact_user_ids = Relationship.where(status: "contact", follower_id: user.id).pluck(:follower_id)
Microposts.where("(visible_for = 'followers' and user_id in (?)) OR (visible_for = "contacts" and user_id in (?)"), following_user_ids, contact_user_ids))