OR

21

ile iki kapsam nasıl birleştirilir? Bir etiket feed'im ve bir arkadaş özet akışım var. Bu ikisini birleştirmek ve nihai "tüm" beslemeyi oluşturmak istiyorum. etiket besleme içinOR

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 

: Arkadaşımız için

beslemek

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 

Ve (ben sayfalandırmada Kaminari mücevher kullanıyorum) kumandadan böyle bir şey çağırır:

@tag_feed = Post.tagfeed(current_user).page(params[:page]).per(21) 
@friend_feed = Post.friendfeed(current_user).page(params[:page]).per(21) 

Şimdi evrensel bir beslemenin olmasını istiyorum, ancak kayboldum. Kapsamlar daraltmak içindir, ancak bu durumda bir VEYA işlemi yapmaya çalışıyorum.

@mother_of_all_feed = @tag_feed + @friend_feed 

gibi şeyler yapmak gereksiz olurdu ve ben tek bir sayfada görünen mesajların sayısını kontrol etmek mümkün olmaz. Bunu yapmak için nasıl gidebilirim? Teşekkürler!

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 

cevap

4

Kendi sorumu yanıtlayan: Ben bu kadarını ilişkilendirmesi etiketleri için arada

. Sanırım bir yolunu buldum.

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

Şimdiye kadar çalışıyor gibi görünüyor, umarım budur!

+6

Performansından memnun musunuz? Burada 4-5 sorgusu var gibi görünüyor. İki seçeneğiniz var gibi görünüyor: ham SQL-sorgu yaz veya en sevdiğim gem squeel'i kullan. OR gerçekleştirir ve iç içe SQL sorgusuna yol açan 'in 'özelliğini destekler. Bir göz atın: https://github.com/ernie/squeel. Http://stackoverflow.com/a/10551561/1322562 gibi birkaç kez "reklam vermeyi" denedim, ancak yalnızca birkaç kişi bunu beğendi. Nedenini merak ediyorum. Squeel ile kapsamlarınızı yeniden kullanabilir ve saf Ruby'de karmaşık sorgu oluşturabilirsiniz: “Product.where” (id.in Product.ruby) | (id.in Product.rails)} 'tek (!!!) SQL sorgusu ile ! – jdoe

+0

Memnun değil, sadece prototip yapıyordum, bu yüzden sorun yok. Squeel'e bir bakacağım. Teşekkürler! – Vlad

17

Bu özelliğin (https://github.com/rails/rails/pull/9052) isteği için bir ray çekme isteği var, ancak bu arada, bazılarınız sizin başlatıcınıza ekleyebileceğiniz veya bir sorgudaki ve kapsamdaki tümceciklere ve kapsamlara izin verebileceğiniz bir maymun yama oluşturdu. size vermek bir ActiveRecord::Relation: aldığımızda

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

, sen muktedir vEYA bu

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

sevdiği kapsamları veya yeni kapsam yazardım

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

Bazı yapıcı eleştiriler, bunu kandıran kişi tarafından takdir edilecektir. Sorunu çözer ve yuvalanmış sorgular oluşturmadan. – keithepley

+3

VEYA Rails 5.0'a eklenecektir: https://github.com/rails/rails/pull/16052 –

+1

Evet, 'OR '," ActiveRecord :: Relation # veya "Rails 5 - http:/dizinine eklenmiştir. /nithinbekal.com/posts/rails-5-features/ – leviathan