使用连接获取关联记录

时间:2018-06-11 13:54:56

标签: sql ruby-on-rails

我有分类,书籍,订单模型

Category.rb

has_many :books

Book.rb

belongs_to :category
has_many :orders

Order.rb

belongs_to :book.

我的任务是将订单放在特定类别上。

我尝试过这两个选项:

使用联接

Order.joins(:book => :category).where('books.category_id = ?', 138)

并使用两个查询:

  1. 查找属于特定类别的book_ids

  2. 找出包含这些book_ids的订单

    book_ids = Book.where(:category_id => 138).pluck(:id)

    Order.where(:book_id => book_ids)。

  3. 我想知道哪一个是正确的。如何才能将订单放在特定类别上?

2 个答案:

答案 0 :(得分:1)

你的第一种方法看起来是正确的,好像应该有效。我将它调整为更多'Railsy',如下所示:

Order.joins(book: :category).where(books: { categories: { id: 138 } })

编辑:实际上,如果您提前知道了类别ID,则可以跳过加载类别,如下所示:

Order.joins(:book).where(books: { category_id: 138 })

这将比第二种方法更有效,因为Rails将优化数据库查询,而您不必将书ID存储在内存中,然后进行第二次交易。

如果您想访问订单book或嵌套category的属性,则应将joins切换为includes - 这会预先加载所有< / em>所需记录,允许您在没有密集和低效的N + 1查询的情况下访问其属性。

这会回答你的问题吗?你有这种方法的问题吗?如果您需要澄清任何内容,请告诉我,我会根据需要进行更新。

答案 1 :(得分:-1)

根据我的经验,使用includes会更好,因为它使用的连接少于连接,从而提供更好的性能 - https://apidock.com/rails/ActiveRecord/QueryMethods/includes

Order.includes(:categories).where('categories.id = ?', id).references(:categories)

这实际上取决于你如何阅读为了理解而发生的事情。