2009-11-06 41 views
1

是否有ActiveRecord执行自定义SQL查询并让它返回一个数组的数组,其中第一行是列名称,每个后面的行是行数据?我要执行类似:如何获得ActiveRecord查询结果中的行和列?

connection.select_rows_with_headers "SELECT id, concat(first_name, ' ', last_name) as name, email FROM users" 

并使其返回:

[["id","name","email"],["1","Bob Johnson","[email protected]"],["2","Joe Smith","[email protected]"]] 

这将允许我打印自定义查询结果以HTML表是这样的:

<table> 
    <% result.each_with_index do |r,i| %> 
    <tr> 
     <% r.each do |c| %> 
     <% if i == 0 %> 
      <th><%=h c %></th> 
     <% else %> 
      <td><%=h c %></td> 
     <% end %> 
     <% end %> 
    </tr> 
    <% end %> 
</table> 

请注意,select_all不起作用,因为每个散列中的键都是无序的,所以您已经失去了查询中指定的结果排序。

回答

2

不正是你要找的,但也许:

connection.execute('select * from users').all_hashes 

,你会回来

[{:id => 1, :name => 'Bob', :email => '[email protected]'},{:id => 1, :name => 'Joe', :email => '[email protected]'}] 

,你可以这样做:

results = connection.execute('select * from users').all_hashes 
munged_results = [] 
columns = results.first.keys.map(&:to_s) 
munged_results << results.first.keys.map(&:to_s) 
munged_results += results.map{|r| columns.map{|c| r[c]} } 

像那

编辑:

results = connection.execute('select * from users').all_hashes 
munged_results = [] 
columns = User.column_names 
munged_results << columns 
munged_results += results.map{|r| columns.map{|c| r[c]} } 

应该正确地命令。

除此之外,还有从#execute返回的结果对象,可以查询信息的位。像#fetch_fields这样的方法可以按顺序获得字段,#fetch_row会将结果集的每一行作为数组(像迭代器一样工作)。再次

编辑:

OK,这里是一个很好的解决方案,修改任何DB你使用:

class Mysql::Result 
    def all_arrays 
    results = [] 
    results << fetch_fields.map{|f| f.name} 

    while r = fetch_row 
     results << r 
    end 

    results 
    end 
end 

这将让他们没有一吨的开销。

使用这样的:

connection.execute('select salt, id from users').all_arrays 
+0

不,不工作,因为哈希键无序 – pjb3

+0

的查询并不总是会SELECT *。他们可能会有一些列或列的子集根据聚合计算等。我更新了问题以使其更清楚。 – pjb3

+1

是的,all_arrays正是我所期待的。希望那里有一些非适配器特定的东西,但我确定为sqlite,postgres和mysql开发并不难。谢谢! – pjb3

相关问题