鉴于以下模型:
用户
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
图书
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
贷款
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
这些关系似乎运作正常。
现在,我想查询用户的所有图书,包括借阅的图书和拥有的图书,我目前正在这样做:
def books
own_books + borrowed_books
end
此方法自然会导致两个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))
此外,我无法运行limit
等活动记录方法或针对此选择进行排序,这样做会很不错。毕竟我从同一张桌子上取书。
我假设有一个更好的(更多“Rails”)和更有效的方法。任何人都想指出我正确的方向?干杯!
P.S。:一个可能的解决方案是为has_many :books
关系定义查询,但这似乎也不正确。
答案 0 :(得分:1)
以下是我最终要做的事情。
使用meta_where gem可以使用以下方法来改善这种情况:
def books
Book.includes(:loans).where({ "owner_id" => self.id } | { "loans.borrower_id" => self.id })
end
此方法返回关系对象并仅生成一个SQL查询。是否应该找到这种方法的意见?现在我正在User
课程中学习。
答案 1 :(得分:0)
在模型中使用它:
def as_json(options={})
super(include: { trades: { include: :trades } })
end