Учитывая следующие модели:
Пользователь
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
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
Эти отношения, кажется, работают нормально.
Теперь я хотел бы запросить все книги для пользователя, включая заимствованные и принадлежащие ему книги, которые я сейчас делаю так:
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
, но это тоже не совсем правильно.