Has_many通过查询
Has_many through query
我有 2 个模型(书籍和作者)和第三个 table 加入他们(has_many 通过关联)。
我正在尝试在我的应用程序中实现搜索,并且 运行 对两个 table 进行查询。我的查询看起来像这样,但我无法找出问题所在:
Book.includes(:authors, :author_books).where("books.title LIKE ? OR authors.name = LIKE ?", "%#{book}%", "%#{book}%")
这是我 运行 得到的错误:
PG::UndefinedTable: ERROR: missing FROM-clause entry for table "authors"
SELECT "books".* FROM "books" WHERE (books.title LIKE '%Harry%' OR authors.name = LIKE '%Harry%')
这是我对三个 table 的架构:
create_table "author_books", force: :cascade do |t|
t.bigint "author_id"
t.bigint "book_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["author_id"], name: "index_author_books_on_author_id"
t.index ["book_id"], name: "index_author_books_on_book_id"
end
create_table "authors", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "books", force: :cascade do |t|
t.string "title"
t.text "description"
t.string "image"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "rating"
t.string "critics"
t.float "price"
end
author_book.rb
class AuthorBook < ApplicationRecord
validates_presence_of :author, :book
belongs_to :author
belongs_to :book
end
author.rb
class Author < ApplicationRecord
validates :name, uniqueness: true
has_many :author_book
has_many :books, through: :author_book
end
book.rb
class Book < ApplicationRecord
validates :title, uniqueness: true, :case_sensitive => false
has_many :author_book
has_many :authors, through: :author_book
has_many :categories, through: :category_book
def self.search_book(book)
if book
Book.joins(:authors, :author_books).includes(:authors, :author_books).where("books.title LIKE ? OR authors.name = LIKE ?", "%#{book}%", "%#{book}%")
end
end
end
我在我的图书控制器中这样调用这个 search_book 方法:
def search
@books = Book.search_book(params[:book])
end
有什么帮助吗?
谢谢!
您忘记加入作者和 author_books 您的关系。 includes
同时加载 :author
和 :author_books
但在不同的查询中。
试试这个:
Book.joins(:authors, :author_books).includes(:authors, :author_books).where("books.title LIKE ? OR authors.name = LIKE ?", "%#{book}%", "%#{book}%")
来自docs
If you want to add conditions to your included models you’ll have to
explicitly reference them.
也就是说,您需要像下面那样将 references(:authors)
添加到您的查询中以解决错误
Book.includes(:authors, :author_books).where("books.title LIKE ? OR authors.name = LIKE ?", "%#{book}%", "%#{book}%").references(:authors)
更新:
Can't join 'Book' to association named 'author_books'; perhaps you
misspelled it?
您应该将 has_many :author_book
替换为 has_many :author_books
,将 through: :author_book
替换为 through: :author_books
我有 2 个模型(书籍和作者)和第三个 table 加入他们(has_many 通过关联)。
我正在尝试在我的应用程序中实现搜索,并且 运行 对两个 table 进行查询。我的查询看起来像这样,但我无法找出问题所在:
Book.includes(:authors, :author_books).where("books.title LIKE ? OR authors.name = LIKE ?", "%#{book}%", "%#{book}%")
这是我 运行 得到的错误:
PG::UndefinedTable: ERROR: missing FROM-clause entry for table "authors"
SELECT "books".* FROM "books" WHERE (books.title LIKE '%Harry%' OR authors.name = LIKE '%Harry%')
这是我对三个 table 的架构:
create_table "author_books", force: :cascade do |t|
t.bigint "author_id"
t.bigint "book_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["author_id"], name: "index_author_books_on_author_id"
t.index ["book_id"], name: "index_author_books_on_book_id"
end
create_table "authors", force: :cascade do |t|
t.string "name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "books", force: :cascade do |t|
t.string "title"
t.text "description"
t.string "image"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "rating"
t.string "critics"
t.float "price"
end
author_book.rb
class AuthorBook < ApplicationRecord
validates_presence_of :author, :book
belongs_to :author
belongs_to :book
end
author.rb
class Author < ApplicationRecord
validates :name, uniqueness: true
has_many :author_book
has_many :books, through: :author_book
end
book.rb
class Book < ApplicationRecord
validates :title, uniqueness: true, :case_sensitive => false
has_many :author_book
has_many :authors, through: :author_book
has_many :categories, through: :category_book
def self.search_book(book)
if book
Book.joins(:authors, :author_books).includes(:authors, :author_books).where("books.title LIKE ? OR authors.name = LIKE ?", "%#{book}%", "%#{book}%")
end
end
end
我在我的图书控制器中这样调用这个 search_book 方法:
def search
@books = Book.search_book(params[:book])
end
有什么帮助吗? 谢谢!
您忘记加入作者和 author_books 您的关系。 includes
同时加载 :author
和 :author_books
但在不同的查询中。
试试这个:
Book.joins(:authors, :author_books).includes(:authors, :author_books).where("books.title LIKE ? OR authors.name = LIKE ?", "%#{book}%", "%#{book}%")
来自docs
If you want to add conditions to your included models you’ll have to explicitly reference them.
也就是说,您需要像下面那样将 references(:authors)
添加到您的查询中以解决错误
Book.includes(:authors, :author_books).where("books.title LIKE ? OR authors.name = LIKE ?", "%#{book}%", "%#{book}%").references(:authors)
更新:
Can't join 'Book' to association named 'author_books'; perhaps you misspelled it?
您应该将 has_many :author_book
替换为 has_many :author_books
,将 through: :author_book
替换为 through: :author_books