Rails 4通过与嵌套属性的多种关系进行查询

时间:2015-04-02 03:42:09

标签: ruby-on-rails ruby-on-rails-4 nested-attributes has-many

我希望找到一个由给定代理人代表的作者数组,但仅限于拥有超过3本书的作者。

例如:如果作者1,5和7有三本以上的书,但作者2,3和6只有一个我的查询应该只返回作者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 ......但我还是找不到如何做到这一点。

3 个答案:

答案 0 :(得分:4)

Author.joins(:books)
  .where(agent_id: params[:id])
  .group(:id)
  .having('count(books.id) > 3')

这将返回Author s

的ActiveRecord关系

<强> PS:
您也可以考虑counter_cache,无需对数据库进行计算即可查询。

在作者表格中添加名为books_count的字段,然后在图书模型中添加此更改:

class Book < ActiveRecord::Base
    belongs_to :author, counter_cache: true
end

这样查询会更容易

Author.where(agent_id: params[:id]).where('books_count > 3')

答案 1 :(得分:2)

它应该是......

Agent.find(params[:id).
  author.select("authors.*, count(books.id) as books_count").joins(:books).
  group_by("authors.id").
  having("books_count > 3")

UPDATE:

Agent.find(params[:id]).authors.select("authors.*, count(books.id) as books_count").joins(:books).group("authors.id").having("books_count > 3")

答案 2 :(得分:0)

这适用于Postgres:

Agent.find(params[:id]).authors.select("authors.*").joins(:books).group("authors.id").having("count(*) > 3")