为什么Rails 3使用Mysql2 Gem的ActiveRecord::Base.connection.execute(sql)返回的是数组而不是哈希表?

12

我正在升级一个应用程序到Rails 3。我决定使用mysql2 gem。在应用程序中有一些旧代码需要进行调用,例如:

results = ActiveRecord::Base.connection.execute(sql)

在2.3.x版本中,它被使用了

results.each_hash do |row|
...
但是使用 gem mysql2 后,结果的类型是 Mysql2::Result,只有一个 each 方法。查看文档,它们指定结果应该是以字段名为键的哈希表,很好!
但实际上,它是一个数组而不是哈希表。
当我在 rails 控制台中实例化自己的 Mysql2::Client 并运行查询时,结果是一个哈希表,这正是我想要的。
在 rails 应用程序中,我认为最好使用 ActiveRecord::Base.connection,因为它已经使用 database.yml 中的选项进行了实例化。
请注意,不幸的是结果不能映射到模型,所以我无法使用它。
目前我所做的是,例如:
result = ActiveRecord::Base.connection.execute(sql)
field_index = result.fields.index("field")
result.each do |row|
  row[field_index]
end

这个东西丑得要命。

有人知道怎么让它返回一个哈希表而不是数组吗?

5个回答

46

我曾经遇到过类似的问题,后来发现这种方法可行:

result = ActiveRecord::Base.connection.execute(sql) 
result.each(:as => :hash) do |row| 
   row["field"] 
end

编辑: 你也可以使用连接对象的 select_all方法 返回一个哈希。


4
这比被选中的答案更好。 - allenhwkim
你能帮我解决一下我的问题吗?http://stackoverflow.com/questions/22997103/find-by-sql-is-not-working-with-prepare-statement - Carlos Morales
这是我想要的。谢谢。 - Rajesh Paul

26

我得到了undefined method 'exec_query' for #<ActiveRecord::ConnectionAdapters::Mysql2Adapter:0x110a0dd48>的错误。 - Ian Vaughan
1
@dsjoerg,谢谢您提供的帮助。我花了很长时间才找到解决这个问题的方法。 - Russell Silva

6
如果你只想重用 database.yml 的配置,你可以这样做:
config = ActiveRecord::Base.configurations[RAILS_ENV].symbolize_keys
conn = Mysql2::Client.new(config)
conn.query("select * from users").each do |user|
  # user should be a hash
end

这比我之前的做法有所改进,所以除非有什么“自动工作”的东西,否则我会使用这个。谢谢。 - pduey
丹,你能帮我解决我的问题吗? http://stackoverflow.com/questions/22997103/find-by-sql-is-not-working-with-prepare-statement - Carlos Morales

2
results = ActiveRecord::Base.connection.select(sql) 

表头

results.first.keys.each do |key|
 key
end

表格数据

results.each do |result| %>
  result.values.each do |value| %>
    value
  end
end

0

改进dan的答案,Rails 3.2.8不接受RAILS_ENV。

    config = ActiveRecord::Base.configurations[Rails.env].symbolize_keys
    conn = Mysql2::Client.new(config)
    conn.query("select * from users").each do |user|
        # user应该是一个哈希值
    end


1
如果@dan的回答有效,请更新他的答案,而不是提供另一个答案。 - Ian Vaughan
@Ian 完成。抱歉创建了一个新答案。 - hammady

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接