2010-07-21 5 views
0

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

  • Publishing House - много книг
  • Книга - имеет одного автора и от одного, и проходит через многие государства
  • Publishing House Автор - писал много книг

Я хотел бы получить панель, которая сказала:

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

Для начала, я думаю, некоторые очень простой код:

@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 } 

Это не очень рельсы, как - мысли?

ответ

1

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

Количество книг издательством

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 specific) и строить даты на основе этого.

Книги конкретного государства

Не совсем уверен, что это правильно WRT ваш DataModel

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

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

+0

Проблема заключается в том, что это приводит к тому, что может быть три раза по размеру sql-запросов. Я думаю, вопрос в том, лучше ли делать три запроса, подобные этому, или потянуть каждую возможную точку данных в массив (с помощью: включает), а затем проанализировать его позже? – aronchick

+0

Пользовательский SQL, чтобы сделать именно то, что вы хотите, вероятно, лучше. Я считаю, что если вы боитесь запускать запрос несколько раз, вероятно, лучше кэшировать данные в столбце в соответствующей таблице и использовать либо триггер, либо обратный вызов для увеличения/декремент. –

Смежные вопросы