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

pdu*_*uey 12 gem mysql2 ruby-on-rails-3

我正在将应用程序升级到Rails 3.我决定使用mysql2 gem.应用程序中有一些遗留代码可以调用:

results = ActiveRecord::Base.connection.execute(sql)
Run Code Online (Sandbox Code Playgroud)

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

results.each_hash do |row|
...
Run Code Online (Sandbox Code Playgroud)

但是使用gem mysql2,结果是类型Mysql2::Result,它只有一个each方法.检查文档并指定结果应该是键入字段名称的哈希值.大!

但事实上,它是一个Array,而不是一个Hash.

当我使用rails控制台并实例化我自己的Mysql2::Client并在那里运行查询时,结果一个Hash,这就是我想要的.

在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
Run Code Online (Sandbox Code Playgroud)

哪个是罪恶的丑陋.

有没有人如何让它返回哈希而不是数组?

Rah*_*Jha 45

我不久前遇到了类似的问题,发现这个问题有效:

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

编辑:您还可以使用返回哈希的连接对象的select_all方法

  • 这比选择的答案要好. (4认同)

dsj*_*erg 26

代替

result = ActiveRecord::Base.connection.execute(sql)
Run Code Online (Sandbox Code Playgroud)

results = ActiveRecord::Base.connection.exec_query(sql)
Run Code Online (Sandbox Code Playgroud)

这就完全符合你的要求.特别是,

results.first
Run Code Online (Sandbox Code Playgroud)

将是一个哈希,依此类推.

感谢@_fx搞清楚这一点!

有关更多信息,请参阅http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Mysql2Adapter.html#method-i-exec_query


dan*_*dan 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
Run Code Online (Sandbox Code Playgroud)