[英]Rails: fetch records at once for has_many and has_many :through associations
Given the following models:鉴于以下模型:
User用户
class User < ActiveRecord::Base
has_many :given_loans, :class_name => "Loan", :foreign_key => "lender_id"
has_many :received_loans, :class_name => "Loan", :foreign_key => "borrower_id"
has_many :borrowed_books, :class_name => "Book", :foreign_key => "borrower_id", :through => :received_loans
has_many :own_books, :class_name => "Book", :foreign_key => "owner_id"
end
Book书
class Book < ActiveRecord::Base
belongs_to :owner, :class_name => "User", :foreign_key => "owner_id"
has_many :loans, :foreign_key => "borrowed_book_id"
has_many :borrowers, :through => "loans", :foreign_key => "borrowed_book_id"
end
Loan贷款
class Loan < ActiveRecord::Base
belongs_to :borrowed_book, :class_name => "Book", :foreign_key => "borrowed_book_id"
belongs_to :borrower, :class_name => "User", :foreign_key => "borrower_id"
belongs_to :lender, :class_name => "User", :foreign_key => "lender_id"
end
These relationships seem to work fine.这些关系似乎运作良好。
Now I'd like to query all books for a user, including both the borrowed books and the owned books, which I'm currently doing like this:现在我想查询用户的所有书籍,包括借来的书籍和拥有的书籍,我目前正在这样做:
def books
own_books + borrowed_books
end
This method naturally causes two SQL queries, though:但是,此方法自然会导致两个 SQL 查询:
Book Load (0.4ms) SELECT "books".* FROM "books" WHERE ("books".owner_id = 1)
Book Load (0.3ms) SELECT "books".* FROM "books" INNER JOIN "loans" ON "books".id = "loans".borrowed_book_id WHERE (("loans".borrower_id = 1))
Furthermore I'm not able to run active record methods such as limit
or order against this selection, which would be nice to have.此外,我无法针对此选择运行活动记录方法,例如
limit
或订单,这会很好。 After all I'm fetching the books from the same table.毕竟我是从同一张桌子上取书。
I'm assuming that there's a better (more "Rails'") and more efficient way of doing this.我假设有一种更好(更多“Rails”)和更有效的方法来做到这一点。 Anyone care to point me into the right direction ?
有人愿意指出我正确的方向吗? Cheers!
干杯!
PS: A possible solution that came to mind was to define a query for a has_many :books
relationship, but that didn't seem quite right either. PS:想到的一个可能的解决方案是为
has_many :books
关系定义一个查询,但这似乎也不完全正确。
Here's what I ended up doing.这就是我最终做的。
Using the meta_where gem the following method is possible to improve the situation:使用meta_where gem 可以通过以下方法来改善这种情况:
def books
Book.includes(:loans).where({ "owner_id" => self.id } | { "loans.borrower_id" => self.id })
end
This method returns a relation object and produces only one SQL query.此方法返回一个关系对象并仅生成一个 SQL 查询。 Any opinions where this method should be located?
这个方法应该放在什么地方有什么意见吗? Right now I'm having it in the
User
class.现在我在
User
类中使用它。
Use this in the model:在模型中使用它:
def as_json(options={})
super(include: { trades: { include: :trades } })
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.