Rails使用group和order来查询关联的表

时间:2015-07-06 21:20:41

标签: ruby-on-rails ruby activerecord rails-activerecord

我正在尝试抓取那些​​最贵的图书位于书店的author条记录:bookworm

以下是我的协会:

#app/models/author.rb
class Author < ActiveRecord::Base
  has_many :books
end

#app/models/book.rb
class Book < ActiveRecord::Base
  belongs_to :author
  belongs_to :book_store
end

#app/models/book_store.rb
class BookStore < ActiveRecord::Base
  has_many :books
end

显示表列的数据库模式的一部分:

#db/schema.rb 
create_table "authors", force: :cascade do |t|
  t.string   "name"
end

create_table "book_stores", force: :cascade do |t|
  t.string   "store_name"
end

create_table "books", force: :cascade do |t|
  t.string   "title"
  t.integer  "cost"
  t.integer  "author_id"
  t.integer  "book_store_id"
end

当我处理此查询时,我认为我应该执行以下操作:

  1. join authorbookbook_store表格

    @authors_books = Author.joins(books: :book_store)
    
  2. {li>

    order author_id, cost

    #first should order by author_id. Then, for author_id ties: it orders by cost in descending order
    @authors_books = @authors_books.order("author_id ASC, cost DESC")
    
    通过author_id
  3. group,检查该作者的第一条记录。如果它的book_store.store_name == 'bookworm'然后返回它。

    #struggling with this part for sure:
    @authors_books = @authors_books.group(:author_id).having("min(book_store.name) like 'bookworm'")
    
  4. 之后,@authors_books应该是uniq作者记录的列表,其中最贵的图书位于书店:bookworm

1 个答案:

答案 0 :(得分:1)

这是解决这个问题的一种方法。首先,在Book模型上创建一个类方法,以获得作者最昂贵的书籍:

# Book model
def self.max_by_author
  max_costs = group(:author_id).select("author_id, MAX(cost) AS max_cost")
  joins("INNER JOIN (#{max_costs.to_sql}) max_costs ON books.author_id = max_costs.author_id AND books.cost = max_costs.max_cost")
end

然后,您可以使用merge将其与BookStore和Author查询相结合,以获得所需内容。要找到#34;书虫和#34;出售的最大书籍。你可以使用:

Book.max_by_author.joins(:book_store).merge(BookStore.where(store_name: "bookworm"))

找到在#34;书虫&#34;出售的最大书籍的作者。你可以使用:

Author.joins(:books).merge(Book.max_by_author.joins(:book_store).merge(BookStore.where(store_name: "bookworm"))).uniq