Rails5 Как я могу создать ленту с объектами отношения ActiveRecord

Я хотел бы создать ленту с микросообщениями:

Сначала я собираю все микропосты от своих подписчиков с 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)

Затем я собираю все микросообщения из моих подписчиков (И статус «контакт») с 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

person Stef Hej    schedule 09.06.2016    source источник
comment
Я думаю, что в первом фрагменте кода есть опечатка: contact_ids_subselect в запросе las SQL должно быть following_ids_subselect?   -  person NickGnd    schedule 09.06.2016
comment
Что такое .paginate метод? Можно ли его применить к перечисляемым объектам?   -  person NickGnd    schedule 09.06.2016
comment
NickGnd ты был прав, я поправил. Paginate ожидает активный объект записи. Например, массивы не могут быть применены (насколько я знаю)   -  person Stef Hej    schedule 10.06.2016


Ответы (1)


#paginate — это метод, доступный только для отношений ActiveRecord. Это означает, что вам нужно будет выбрать нужные данные в одном запросе.

Итак, если я правильно читаю ваш пример, вы хотите, чтобы все Micropost от пользователей, на которых подписан текущий пользователь, были видны для contacts или following.

Вы можете выбрать их в одном запросе, например так

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))
person patkoperwas    schedule 09.06.2016
comment
дает мне undefined method 'followeds' for 1:Fixnum. Когда я пытаюсь .where(user_id: user.following.pluck(:id)), я получаю undefined method 'following' for 1:Fixnum - person Stef Hej; 10.06.2016
comment
Я хочу, чтобы все микросообщения от пользователей, за которыми следит текущий пользователь, с visible_for 'followers' + все микросообщения от пользователей, за которыми следит текущий пользователь, с status 'contact' с visible_for 'contacts' - person Stef Hej; 10.06.2016
comment
Ах, это, вероятно, потому, что у вас есть целое число, а не пользовательский объект. User.find(user_id).followeds.pluck(:id) - person patkoperwas; 10.06.2016
comment
хорошо, но это также возвращает мне микросообщения от пользователей, на которых подписан текущий пользователь, без status 'contact' и visible_for 'contacts - person Stef Hej; 10.06.2016
comment
запрос на самом деле не отличается между микросообщениями об отношениях и микросообщениями об отношениях с status 'contact'. Запрос не должен содержать микросообщения от пользователей, на которых текущий пользователь подписан с visible_for 'contacts'. Он должен содержать (а) микросообщения от пользователей, на которых текущий пользователь подписан с помощью visible_for 'follower', и (б) микросообщения от пользователей, на которые текущий пользователь подписан с помощью status 'contact' с помощью visible_for 'contacts'. - person Stef Hej; 10.06.2016