Ruby / Rails收藏到收藏

时间:2020-03-05 18:57:49  来源:igfitidea点击:

我有两个表与一个联接表联接,这只是伪代码:

Library
Book
LibraryBooks

我需要做的是,如果我有一个图书馆的ID,我想获取该图书馆所有书籍所在的所有图书馆。

因此,如果我有图书馆1,而图书馆1中有书籍A和B,书籍A和B在图书馆1、2和3中,是否有一种优雅的(单行)方式在轨道上做到这一点?

我刚在想:

l = Library.find(1)
allLibraries = l.books.libraries

但这似乎不起作用。有什么建议吗?

解决方案

回答

可能:

l.books.map {|b| b.libraries}

或者

l.books.map {|b| b.libraries}.flatten.uniq

如果我们希望将它们全部放在一个平面阵列中。

当然,我们实际上应该将此定义为Library上的一种方法,以支持封装的崇高原因。

回答

如果要返回一维库数组,请删除重复项。

l.books.map{|b| b.libraries}.flatten.uniq

回答

一个问题

l.books.map{|b| b.libraries}.flatten.uniq

是它将为l中的每本书生成一个SQL调用。更好的方法(假设我了解架构)可能是:

LibraryBook.find(:all, :conditions => ['book_id IN (?)', l.book_ids]).map(&:library_id).uniq

回答

l = Library.find(:all, :include => :books)
l.books.map { |b| b.library_ids }.flatten.uniq

请注意,map(&:library_ids)map {| b | Ruby 1.8.6中的b.library_ids},而1.9.0中的速度更快。

我还要提到的是,如果我们在此处使用:joins而不是include,它将在同一查询中找到所有的库和相关书籍,从而加快了数据库的运行时间。 :joins仅在图书馆有书的情况下有效。