21

我有一個標籤源和一個好友源。 我想結合這兩個並構建最終的「全部」飼料。如何將兩個示波器組合在一起或者是

對於朋友訂閱:

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) 

現在我想擁有一個通用飼料,但我迷路了。範圍是爲了縮小範圍,但在這種情況下,我試圖執行OR操作。這樣做的東西像

@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 

回答

4

回答我的問題。我想我想出了一個辦法。

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.*") 
) 

它似乎到目前爲止,希望這是它!

+6

你對它的性能滿意嗎?看起來你在這裏得到4-5個查詢。看起來你有兩個選擇:編寫原始的SQL查詢或使用我最喜歡的gem squeel。它允許執行OR並支持導致嵌套SQL查詢的'in'功能。看看:https://github.com/ernie/squeel。我嘗試了幾次「做廣告」,像這樣:http://stackoverflow.com/a/10551561/1322562,但只有少數人喜歡它。我想知道爲什麼。通過使用squeel,您可以重複使用您的作用域並在純Ruby中構建複雜的查詢,如:通過單一(!!!)SQL查詢生成Product.where {(id.in Product.ruby)|(id.in Product.rails)}' ! – jdoe

+0

不滿意,但我只是原型,所以沒關係。我會看看squeel。謝謝! – Vlad

17

對此功能(https://github.com/rails/rails/pull/9052)有一個滑軌拉取請求(https://github.com/rails/rails/pull/9052),但同時,有人創建了一個猴子修補程序,您可以在初始化程序中包含這些修補程序,以允許您在一個查詢中使用範圍和where子句,但仍然給你一個ActiveRecord::Relation

https://gist.github.com/j-mcnally/250eaaceef234dd8971b

就這樣,你能或者你的範圍這樣

Post.tagfeed(current_user).or.friendfeed(current_user) 

或寫一個新的範圍

scope :mother_of_all_feed, lambda{|user| tagfeed(user).or.friendfeed(user)} 
+3

一些建設性的批評將受到任何人低估這一點的讚賞。它解決了這個問題,並且不會生成嵌套查詢。 – keithepley

+3

OR將被添加到Rails 5.0中:https://github.com/rails/rails/pull/16052 –

+1

是的,OR已經被添加到Rails 5中的ActiveRecord :: Relation#或者' /nithinbekal.com/posts/rails-5-features/ – leviathan