Как объединить две области с OR
У меня есть фид тегов и фид друга.
Я хочу объединить эти два и построить конечный "все" фид.
Для друга:
class Post < ActiveRecord::Base
scope :friendfeed, lambda{|x| followed_by}
def self.followed_by(user)
where("user_id IN (?) OR user_id = ?", user.watched_ids, user.id)
end
end
Для фида тегов:
class Post < ActiveRecord::Base
scope :tagfeed, lambda{|x| infatuated_with}
def self.infatuated_with(user)
joins(:attachments).where("attachments.tag_id IN (?)", user.tags).select("DISTINCT pages.*")
end
end
И я бы назвал что-то вроде этого от контроллера (я использую камень Каминари для разбивки на страницы):
@tag_feed = Post.tagfeed(current_user).page(params[:page]).per(21)
@friend_feed = Post.friendfeed(current_user).page(params[:page]).per(21)
Теперь я хочу иметь универсальный фид, но я потерян. Области предназначены для сужения, но в этом случае я пытаюсь выполнить операцию ИЛИ. Делать такие вещи, как
@mother_of_all_feed = @tag_feed + @friend_feed
будет избыточным, и я не смогу контролировать количество сообщений, появляющихся на одной странице. Как я могу это сделать? Спасибо!
Кстати, для тегов у меня установлена ассоциация следующим образом:
class Post < ActiveRecord::Base
has_many :attachments
has_many :tags, :through => :attachments
end
class Tag < ActiveRecord::Base
has_many :attachments
has_many :posts, :through => :attachments
end
class Attachment < ActiveRecord::Base
belongs_to :tag
belongs_to :post
end
Ответы
Ответ 1
Отвечая на мой вопрос. Кажется, я понял путь.
where("pages.id IN (?) OR pages.id IN (?)",
Page.where(
"user_id IN (?) OR user_id = ?",
user.watched_ids, user.id
),
Page
.joins(:attachments)
.where("attachments.tag_id IN (?)", user.tags)
.select("DISTINCT pages.*")
)
Кажется, он работает до сих пор, надеюсь, что это так!
Ответ 2
Там рельсы тянут запрос для этой функции (https://github.com/rails/rails/pull/9052), но в то же время кто-то создал патч обезьяны, который вы может включать в ваши инициализаторы, которые позволят вам или областям и где предложения в одном запросе, и все равно дают вам ActiveRecord::Relation
:
https://gist.github.com/j-mcnally/250eaaceef234dd8971b
При этом вы сможете использовать OR, например,
Post.tagfeed(current_user).or.friendfeed(current_user)
или написать новую область
scope :mother_of_all_feed, lambda{|user| tagfeed(user).or.friendfeed(user)}