views:

821

answers:

3

Hi all,
I'm doing custom find_by_sql queries which are dynamically created by user input. What is the best way to find the field names returned by find_by_sql
I've tried using columns, column_names and keys methods but none work. Is the ActiveRecord result a hash or an array?

e.g.

@fm_reports = FmReport.find_by_sql(crosstab_query)
field_names = @fm_reports.keys (or .columns or .column_names)

Cheers, Keith

Update ::

It seems that unless you do "select * from ...." in a find_by_sql it does not return the attribute names

>> FmReport.find_by_sql("select object_class, alarm_mr from fm_reports limit 1") 
=> [#<FmReport >] 
>> FmReport.find_by_sql("select * from fm_reports limit 1") 
=> [#<FmReport id: 7, ALARM_DN: "PLMN-PLMN/BSC-31569/TCSM-72", ALARM_OBJECT: "MELB_BSC1", ALARM_MR: "VIC_METRO", PARENT_DN: "PLMN-PLMN/BSC-31569", PARENT_CLASS: "BSC", OBJECT_CLASS: "TCSM", ALARM_NUMBER: "2955", ALARM_TIME: "21/12/2009 11:02:19", CANCEL_TIME: "21/12/2009 11:03:27", SEVERITY: "2", created_at: nil, updated_at: nil>] 
A: 

Maybe you're looking for #attributes?

Also, find_by_sql returns an Array so that's why there's no method called attributes. How about doing first.attributes on the result of your find?

Another question is why are you using find_by_sql at all?

Why not just use ActiveRecord's built in stuff for this?

SomeModel.find( :all, :limit => 1 ).first.attributes
thenduks
Thanks, I've updated the original question as it seems find_by_sql only returns attributes if you do a select * from ...
Keith Muggleton
Hi, the limit 1 was just an example save churning 800k + lines,basically my controller creates a crosstab/pivot query dynamically based on user input and then displays the ouput. So the query has SUM and COUNT functions within it.I've found workarounds for my issue (none of which actually fix the original problem) so I'll carry on with it, and post an answer if I get one that works for my situation.Thanks for all you help.
Keith Muggleton
PS this is the kind of query that is produced -select ALARM_MR as row_name,SUM(IF(PARENT_CLASS = "BCF", 1 , 0)) AS `BCF`,SUM(IF(PARENT_CLASS = "BSC", 1 , 0)) AS `BSC`,SUM(IF(PARENT_CLASS = "BTS", 1 , 0)) AS `BTS`,SUM(IF(PARENT_CLASS = "FRBC", 1 , 0)) AS `FRBC`,SUM(IF(PARENT_CLASS = "ROOT", 1 , 0)) AS `ROOT`,SUM(IF(PARENT_CLASS = "WBTS", 1 , 0)) AS `WBTS`,count(1) as `Total` from fm_reports group by ALARM_MR
Keith Muggleton
A: 

http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M002353

attribute_names

Daniel
Thanks Dan, I did try attribute_names but it kept saying unknown method
Keith Muggleton
What version of rails are you running?
Daniel
+1  A: 
@fm_reports = FmReport.find_by_sql(crosstab_query)
field_values = @fm_reports.attributes
field_values.each {|key, value| puts key}

The above line will return a hashmap of field-names and their values. They can be iterated on if req.

Priyank
Thanks Priyank, I tried this, but it still says undefined method `attributes' for #<Array:0x341631c>
Keith Muggleton