这个ruby方法可以重构吗?

Can this ruby method be refactored?

一个user有多个libraries,每个图书馆有多个books。我想知道用户在他的图书馆中是否有一本书。我用以下方法调用此方法:current_user.has_book?(book):

def has_book?(book)
  retval = false
  libraries.each do |l|
    retval = true if l.books.include?(book)
  end
  return retval
end

我的方法可以重构吗?

这看起来是最小化的版本,我看不出有什么办法可以进一步缩小它:

def has_book?(a)c=false;libraries.each{|b|c=true if b.books.include?a};c end

我不知道为什么@Зелёный 删除了他的回答,但我认为这是一个很好的答案,所以我将其粘贴在这里:

def has_book?(book)
  libraries.includes(:books)
           .where(books: {id: book.id})
           .any?
end
def has_book?(book)
  libraries.map { |l| l.books.include?(book) }.any?
end

map 将图书馆对象的集合转换为布尔集合,具体取决于它们是否包含书籍,并且 any? returns true 如果其中的任何元素数组是 true.

这行数较少,但如果您在找到包含该书的图书馆后立即 return true,您的原始解决方案可能会更有效。

def has_book?(book)
  libraries.each do |l|
    return true if l.books.include?(book)
  end
  return false
end

顺便说一句。 php 和 ruby 几乎同时出现。

def has_book?(book)
    libraries.any?{|lib| lib.books.include?book}
end

几乎是我能想到的最简单的。 虽然不安全。