[英]Two belong_to referring the same table + eager loading
First of all, based on this ( Rails association with multiple foreign keys ) I figured out how to make two belong_to pointing to the same table. 首先,基于此( Rails与多个外键的关联 ),我弄清楚了如何使两个belong_to指向同一张表。
I have something like that 我有这样的东西
class Book < ApplicationRecord
belongs_to :author, inverse_of: :books
belongs_to :co_author, inverse_of: :books, class_name: "Author"
end
class Author < ApplicationRecord
has_many :books, ->(author) {
unscope(:where).
where("books.author_id = :author_id OR books.co_author_id = :author_id", author_id: author.id)
}
end
It's all good. 都很好。 I can do either 我可以
However, sometimes I need to eager load books for multiple authors (to avoid N queries). 但是,有时我需要为多位作者加载书籍(以避免N个查询)。
I am trying to do something like: 我正在尝试做类似的事情:
Author.includes(books: :title).where(name: ["Lewis Carroll", "George Orwell"])
Rails 5 throws at me: "ArgumentError: The association scope 'books' is instance dependent (the scope block takes an argument). Preloading instance dependent scopes is not supported." Rails 5向我抛出:“ ArgumentError:关联范围'books'是实例相关的(scope块带有一个参数)。不支持预加载实例相关的范围。”
I am trying to figure out what I should do? 我想弄清楚该怎么办?
Should I go with many-to-many association? 我应该参加多对多协会吗? It sounds like a solution. 听起来像是一个解决方案。 However, it looks like it will introduce it's own problems (I need "ordering", meaning that I need explicitly differentiate between main author and co-author). 但是,它似乎会引入自己的问题(我需要“排序”,这意味着我需要明确区分主要作者和合著者)。
Just trying to figure out whether I am missing some simpler solution... 只是想弄清楚我是否缺少一些更简单的解决方案...
Why do you not use HABTM relation? 为什么不使用HABTM关系? For example: 例如:
# Author model
class Author < ApplicationRecord
has_and_belongs_to_many :books, join_table: :books_authors
end
# Book model
class Book < ApplicationRecord
has_and_belongs_to_many :authors, join_table: :books_authors
end
# Create books_authors table
class CreateBooksAuthorsTable < ActiveRecord::Migration
def change
create_table :books_authors do |t|
t.references :book, index: true, foreign_key: true
t.references :author, index: true, foreign_key: true
end
end
end
You can use eagerload like as following: 您可以使用eagerload,如下所示:
irb(main):007:0> Author.includes(:books).where(name: ["Lewis Carroll", "George Orwell"])
Author Load (0.1ms) SELECT "authors".* FROM "authors" WHERE "authors"."name" IN (?, ?) LIMIT ? [["name", "Lewis Correll"], ["name", "George Orwell"], ["LIMIT", 11]]
HABTM_Books Load (0.1ms) SELECT "books_authors".* FROM "books_authors" WHERE "books_authors"."author_id" IN (?, ?) [["author_id", 1], ["author_id", 2]]
Book Load (0.1ms) SELECT "books".* FROM "books" WHERE "books"."id" IN (?, ?) [["id", 1], ["id", 2]]
尝试这个:
Author.where(name: ["Lewis Carroll", "George Orwell"]).include(:books).select(:title)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.