Элегантное суммирование / группировка / и т.д. в рельсах - PullRequest
0 голосов
/ 22 июля 2010

У меня есть несколько объектов, которые связаны друг с другом, и я хотел бы расположить несколько панелей мониторинга, чтобы показать их. Ради аргумента:

  • Издательство - много книг
  • Книга - имеет одного автора и принадлежит одному, и проходит через множество состояний
  • Издательский Дом Автор - Написал много книги

Я бы хотел получить панель с надписью:

  • Сколько книг издало издательство в этом месяце?
  • Сколько книг в автор написал в этом месяце?
  • В каком состоянии находится (в процессе публикации, публикации) каждая из книг?

Начнем с того, что я думаю очень простой код:

@all_books = Books.find(:all, :joins => [:author, :publishing_house], :select => "books.*, authors.name, publishing_houses.name", :conditions => ["books.created_at > ?", @date])

Затем я перехожу к каждому из необходимых мне подэлементов и суммирую их в новые массивы, например:

@ph_stats = {}
@all_books.map {|book| @ph_stats[book.publishing_house_id] = (@ph_stats[book.publishing_house_id] || 0) + 1 }

Это не похоже на рельсы - мысли?

Ответы [ 2 ]

1 голос
/ 22 июля 2010

Вы действительно должны думать о SQL, необходимом для написания такого запроса, поэтому следующие запросы должны работать во всех базах данных:

Количество книг по публикацииhouse

PublishingHouse.all(:joins => :book, :select => "books.publishing_house_id, publishing_houses.name, count(*) as total", :group => "1,2")

Количество книг, написанных автором в этом месяце

Если вы собираетесь переместить это в сферу - вам нужно будет поместить этов лямбде

Author.all(:joins => :books, :select => "books.author_id, author.name, count(*) as total", :group => "1,2", :conditions => ["books.pub_date between ? and ?", Date.today.beginning_of_month, Date.today.end_of_month])

это связано с использованием Date.today, в качестве альтернативы - вы можете использовать now () :: date (для postgres) и строить даты на основе этого.

Книги определенного состояния

Не совсем уверен, что это правильно с вашей моделью данных

Book.all(:joins => :state, :select => "states.name, count(*) as total", :group => "1")

Все сделано с помощью магии SQL.

1 голос
/ 22 июля 2010

Я думаю, что вам лучше всего объединить именованные области, чтобы вы могли делать такие вещи, как:

@ books = Books.published.this_month

http://api.rubyonrails.org/classes/ActiveRecord/NamedScope/ClassMethods.html#M001683 http://m.onkey.org/2010/1/22/active-record-query-interface

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...