2015-09-17 19 views
5

Jeśli mam kolekcję Post s, czy mimo to otrzymuję wszystkie Comment s dla wszystkich tych postów przy użyciu metody łańcuchów lub zakresów?Uzyskiwanie wszystkich dzieci kolekcji z wieloma relacjami

Na przykład:

posts = Post.where(published: true) 
comments = posts.comments 

# vs 
comments = [] 
posts.each do |post| 
    comments.push(post.comments) 
end 

Odpowiedz

2

Najlepszy sposób:

Comment.joins(:post).where(post: {published: true}) 

lub jeśli masz zmienną posts, która jest relacją ActiveRecord:

Comment.joins(:post).where(post: posts) 
2

Oczywiście, istnieje kilka sposobów. Możesz użyć map i flatten, co jest dobre dla małej liczby rekordów. Upewnij się, że komentarze zostały załadowane zbiorczo za pomocą includes.

Post.where(published: true).includes(:comments).map(&:comments).flatten 

Lub możesz użyć złączenia. To sprawia, że ​​więcej pracy w bazie danych, która jest prawdopodobnie szybsza, ale zależy od twojego schematu i zestawu danych. Zwykle będziesz chciał użyć uniq, aby zapobiec duplikatom.

posts = Post.where(published: true) 
Comment.joins(:post).merge(posts).uniq 

Upewnij się również, że w pełni kwalifikujesz wszystkie jawne fragmenty w klauzulach na połączonych tabelach, np. użyj where('posts.created_at < ?', ...) zamiast where('created_at < ?', ...).

Edit:

Kolejny wariant pierwszy, w przypadku, gdy chcesz powrócić relację (co może być dalej scoped dół linii):

Comment.where(id: Post.where(published: true).pluck(:id)) 
+0

Może 'Comment.where (post_id:'? – hlcs

Powiązane problemy