views:

101

answers:

2

Here is my data model from my application:

id :integer(4) not null, primary key spam :boolean(1) not null duplicate :boolean(1) not null ignore :boolean(1) not null brand_id :integer(4) not null attitude :string not null posted_at :datetime not null

Attitude could have 3 states: negative, positive, neutral.

I want to generate resultset in table, this way, for each day between start and end date:

date       | total | positive | neutral | negative
2009-10-10 |   12  |     4    |    7    |     1
(...)
2009-10-30 |   5   |     2    |    1    |     1

And ignore all records which have:

duplicate = true ignore = true spam = true

How it's could be done?

A: 
Data.all  :select     => "DATE(posted_at) AS date,
                          COUNT(*) AS total,
                          SUM(attitude = 'positive')  AS positive,
                          SUM(attitude = 'neutral')   AS neutral,
                          SUM(attitude = 'negative')  AS negative",
          :conditions => [  "duplicate <> ? AND ignore <> ? AND spam <> ?",
                            true, true, true ],
          :group      => :date,
          :order      => :date

That should give you the data you want; I leave it as an exercise for the reader to render it into a table. (SQL gurus: please feel free to check my work.)

Jordan
This code won't work:<pre>class Brand < ActiveRecord::Base has_many :messages, :dependent => :destroy def report() self.messages.find(:all, :select => "DATE(posted_at) AS date, COUNT(*) AS total, SUM(attitude = 'positive') AS positive, SUM(attitude = 'neutral') AS neutral, SUM(attitude = 'negative') AS negative", :group => :date, :order => :date) endend>> Brand.find(1).report=> [#<Message >]>> </pre>
Arywista
https://gist.github.com/77695da9dc3e2ecef1ff
Arywista
It looks like it's returning one row. Do you have more than one day's worth of data? What are the values of Message#total, Message#positive, etc?
Jordan
https://gist.github.com/f8b91fd11532f5474026 - it looks ok (for many days posted_at many values)
Arywista
I executed this sql in console (is generated by above method) and everything works fine:" SELECT DATE(posted_at) AS date, COUNT(*) AS total, SUM(attitude = 'positive') AS positive, SUM(attitude = 'neutral') AS neutral, SUM(attitude = 'negative') AS negative FROM `messages` WHERE (`messages`.brand_id = 1) AND (`messages`.`spam` = 0 AND `messages`.`duplicate` = 0 AND `messages`.`ignore` = 0) GROUP BY date ORDER BY date, posted_at DESC"But i think rails mapping to model breaks everthing.
Arywista
You didn't answer my question. Please tell me the contents of the Message object that Brand#report is returning. A quick way to do this on the console is Brand.find(1).report.to_yaml
Jordan
A: 

Have a look at Jasper Reports. I use it for all my applications. Its easy to use and setup. Its also easier to manager sub reports etc without polluting your application code base.

Warren Noronha