这是我最初的问题。我有以下两种型号。
class Author < ActiveRecord::Base
has_many :books
end
和
class Book < ActiveRecord::Base
belongs_to :author
scope :available, ->{ where(available: true) }
end
我想让Author加入Book的范围“可用”。以下是我想在数据库上执行的查询。可以这样做吗?
Select authors.* , count(books.*) as books_count
From authors left outer join books on books.author_id = authors.id
and books.available = true
group by (authors.id) order by books_count;
我尝试了以下方法
Author.joins("LEFT OUTER JOIN authors on books.author_id = authors.id")
.merge(Book.available)
.select("authors.* , count(books.*) as books_count")
.group("authors.id").order("books_count")
但这会导致以下查询。
Select authors.* , count(books.*) as books_count
From authors left outer join books on books.author_id = authors.id
where books.available = true
group by (authors.id) order by books_count;
因此,它将删除所有没有书的作者。
重要提示:我的AR版本没有left_outer_joins方法
答案 0 :(得分:0)
您需要再添加一个查询,该查询将检查作者是否没有书籍,然后我们需要添加它。请尝试下面的查询
Author.joins("LEFT OUTER JOIN authors on books.author_id = authors.id")
.merge(Book.available)
.where("books.author_id IS NULL")
.select("authors.* , count(books.*) as books_count")
.group("authors.id").order("books_count")
答案 1 :(得分:0)
虽然它不使用您的范围。 (主要是因为您的范围包括您不希望在查询中使用的where子句)
您可以使用arel
执行此操作,例如:
book_table = Book.arel_table
author_table = Author.arel_table
author_join = author_table.join(book_table,Arel::Nodes::OuterJoin)
.on(book_table[:author_id].eq(author_table[:id]).and(
book_table[:available].eq(true)
)
)
Author.joins(author_join.join_sources)
.select("authors.* , count(books.*) as books_count")
.group("authors.id").order("books_count")
这将导致以下SQL:
SELECT
authors.* ,
count(books.*) as books_count
FROM
authors
LEFT OUTER JOIN books ON books.author_id = authors.id
AND books.available = true
GROUP BY
authors.id
ORDER BY
books_count