Rails 4 通过与 nested_attributes 的 has_many 关系进行查询
Rails 4 querying through has_many relationships with nested_attributes
我正在寻找由给定代理代表的一组作者,但仅限拥有超过 3 本书的作者。
例如:如果作者 1、5 和 7 有超过三本书,而作者 2、3 和 6 只有 1 本,我的查询应该只return 作者 1、5、7。
class Agent < ActiveRecord::Base
has_many :books
has_many :authors
end
class Book < ActiveRecord::Base
belongs_to :author
belongs_to :agent
end
class Author < ActiveRecord::Base
has_many :books
belongs_to :agent
end
这是我试过的。我很难过
agents_controller.rb
def show
@agent = Agent.find(params[:id])
@authors = @agent.authors
@books = @authors.books
@popular = @authors.where(@books.count > 3)
end
没有任何效果。我觉得我应该能够迭代,然后在@books 的集合中找到不同的或唯一的@author_ids...但我一直无法找到如何做到这一点。
应该是这样的..
Agent.find(params[:id).
author.select("authors.*, count(books.id) as books_count").joins(:books).
group_by("authors.id").
having("books_count > 3")
更新:
Agent.find(params[:id]).authors.select("authors.*, count(books.id) as books_count").joins(:books).group("authors.id").having("books_count > 3")
这适用于 Postgres:
Agent.find(params[:id]).authors.select("authors.*").joins(:books).group("authors.id").having("count(*) > 3")
Author.joins(:books)
.where(agent_id: params[:id])
.group(:id)
.having('count(books.id) > 3')
这将 return Author
s
的 ActiveRecord 关系
PS:
您可能还想考虑 counter_cache
,您将能够在不对数据库进行计算的情况下进行查询。
在作者 table 中添加一个名为 books_count
的字段,然后在书籍模型中添加此更改:
class Book < ActiveRecord::Base
belongs_to :author, counter_cache: true
end
这样查询会方便很多
Author.where(agent_id: params[:id]).where('books_count > 3')
我正在寻找由给定代理代表的一组作者,但仅限拥有超过 3 本书的作者。
例如:如果作者 1、5 和 7 有超过三本书,而作者 2、3 和 6 只有 1 本,我的查询应该只return 作者 1、5、7。
class Agent < ActiveRecord::Base
has_many :books
has_many :authors
end
class Book < ActiveRecord::Base
belongs_to :author
belongs_to :agent
end
class Author < ActiveRecord::Base
has_many :books
belongs_to :agent
end
这是我试过的。我很难过
agents_controller.rb
def show
@agent = Agent.find(params[:id])
@authors = @agent.authors
@books = @authors.books
@popular = @authors.where(@books.count > 3)
end
没有任何效果。我觉得我应该能够迭代,然后在@books 的集合中找到不同的或唯一的@author_ids...但我一直无法找到如何做到这一点。
应该是这样的..
Agent.find(params[:id).
author.select("authors.*, count(books.id) as books_count").joins(:books).
group_by("authors.id").
having("books_count > 3")
更新:
Agent.find(params[:id]).authors.select("authors.*, count(books.id) as books_count").joins(:books).group("authors.id").having("books_count > 3")
这适用于 Postgres:
Agent.find(params[:id]).authors.select("authors.*").joins(:books).group("authors.id").having("count(*) > 3")
Author.joins(:books)
.where(agent_id: params[:id])
.group(:id)
.having('count(books.id) > 3')
这将 return Author
s
PS:
您可能还想考虑 counter_cache
,您将能够在不对数据库进行计算的情况下进行查询。
在作者 table 中添加一个名为 books_count
的字段,然后在书籍模型中添加此更改:
class Book < ActiveRecord::Base
belongs_to :author, counter_cache: true
end
这样查询会方便很多
Author.where(agent_id: params[:id]).where('books_count > 3')