2016-03-31 17 views
1

Belirli bir örneğim var, ancak genel soru şudur: Bir dizi filtre değeri eşleştiğinde kayıt almanın en iyi yolu nedir? Kronolojik senin aşağıdakilerden gelen yayınları sipariş döndürür bir işlev yazmak istiyorumRuby on Rails, filtre değerleri dizisi ile en uygun aramayı?

class Relationship < ActiveRecord::Base 
    belongs_to :follower, class_name: "User" 
    belongs_to :followed, class_name: "User" 
    validates :follower_id, presence: true 
    validates :followed_id, presence: true 
end 

:

Ben Kullanıcı has_many :posts

ve ben şöyle bir Relationship modeli var User ve Post kayıtları var ki 'takip etme - diğer bir deyişle, takip ettiğiniz kullanıcıların takip ettikleri kullanıcılardan kopyalarını ve yayınlarını hariç tuttuğunuz tüm yayınlar. Daha sonra görevlerinden ve düzeni onları derlemek

users = [] 
@user.following.each do |f| 
    f.following.each do |ff| 
    users << ff 
    end 
end 

# dedupe 
users = users.uniq 

#remove self and following 
users.delete(@user) 
@user.following.each do |f| 
    users.delete(f) 
end 

:

Çözümümün ilk ilgi tüm kullanıcıların bir dizi derlemek etmektir

posts = [] 
users.each do |u| 
    posts += u.posts 
end 
posts.sort_by!{|x| x[:created_at]}.reverse! 

Bunu yapmak için daha iyi bir yolu olduğunu düşünüyorum Aktif Kayıt işlevleri ile ancak bunların bir dizi ile nasıl çalışacağını anlayamıyorum. Mesela ben id değerleri yerine tam modellerin Kullanıcı dizisi derlemek ve eğer sonrası dizisini almak için bu kodu çalıştırmayı deneyin:

posts = Post.where(
    user_id: user_ids 
).order('created_at DESC').limit(21) 

boş bir dizi döndürür. Mevcut çözümümden bir dizi filtre değeriyle arama yapmanın daha iyi bir yolu var mı?

Güncelleme: ek modal kodu:

class Post < ActiveRecord::Base 
    belongs_to :user 
    ... 

User.rb user_ids kullanmanın

class User < ActiveRecord::Base 
    has_many :photos 
    has_many :active_relationships, class_name: "Relationship", 
           foreign_key: "follower_id", 
           dependent: :destroy 
    has_many :passive_relationships, class_name: "Relationship", 
           foreign_key: "followed_id", 
           dependent: :destroy 
    has_many :following, through: :active_relationships, source: :followed 
    has_many :followers, through: :passive_relationships, source: :follower 
    ... 
+0

Bir "Kullanıcı" has_many mu: followings, as:: follower, class_name: 'İlişki' '? – Aetherus

+0

evet, daha çok modal kodla güncelledim – Cbas

+0

ActiveRecord koleksiyonları üzerinde yineleme yaparken, 'her 'yerine' find_each' kullanın. 'find_each', toplu olarak koleksiyondaki kayıtları bir kerede değil, aynı zamanda bellek yükünüz için daha güvenli bir şekilde yükler. –

cevap

1

Fikrin iyi biridir. Bu sorgu boş bir dizi döndürdüyse, user_id'lerinin beklediğiniz gibi olduğundan emin olmak için kontrol ettiniz mi?

Kod gelince, Enumerable#map ve #flat_map'a bakmanız gerekir. #each döngülerinde yapmaya çalıştığınız şeyi gerçekleştirmek için yerleşik yakut yöntemleri vardır.

user_ids = user.followings.flat_map { |following| following.following_id } 
user_ids.uniq! 
user_ids -= [user.id, user.following_ids].flatten 
Post.where(user_id: user_ids).order(id: :desc).limit(21) 

Not: Kodunuz gibi bir şeye düşürebilir created_at kimliğinin oluşturulma sırasını takip etmelidir beri, o bir dizin olmalıdır çünkü id yerine created_at dayalı arıyor ele alacak.