Почему Rails 3 с Mysql2 Gem ActiveRecord:: Base.connection.execute(sql) возвращает Array not Hash?
Я сейчас обновляю приложение до Rails 3. Я решил пойти с gem mysql2. В приложении есть какой-то унаследованный код, который вызывает такие вызовы, как:
results = ActiveRecord::Base.connection.execute(sql)
В версии 2.3.x он использовал
results.each_hash do |row|
...
Но с gem mysql2 результатом является тип Mysql2::Result
, который имеет только метод each
. Проверяемые документы, и они указывают, что результаты должны быть хешированы с именем поля. Отлично!
Но на самом деле это Array
, а не Hash
.
Когда я использую консоль rails и создаю экземпляр собственного Mysql2::Client
и запускаю там запрос, результаты будут Hash
, и это то, что я хочу.
В приложении rails лучше использовать ActiveRecord::Base.connection
, поскольку он был создан с помощью параметров из базы данных .yml.
Обратите внимание: к сожалению, результат не сопоставляется с моделью, поэтому я не могу ее использовать.
То, что я сделал сейчас, это, например:
result = ActiveRecord::Base.connection.execute(sql)
field_index = result.fields.index("field")
result.each do |row|
row[field_index]
end
Что является уродливым как грех.
Кто-нибудь, как я могу заставить его вернуть хеш вместо массива?
Ответы
Ответ 1
Если вы просто хотите повторно использовать конфигурацию 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
Ответ 2
Я столкнулся с подобной проблемой некоторое время назад и нашел, что это работает:
result = ActiveRecord::Base.connection.execute(sql)
result.each(:as => :hash) do |row|
row["field"]
end
edit: вы также можете использовать метод select_all объекта соединения, который возвращает хэш
Ответ 3
вместо
result = ActiveRecord::Base.connection.execute(sql)
делать
results = ActiveRecord::Base.connection.exec_query(sql)
И это будет делать именно то, что вы хотите. В частности,
results.first
будет хешем и т.д.
Благодаря @_fx для выяснения этого!
Подробнее см. http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/Mysql2Adapter.html#method-i-exec_query
Ответ 4
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
Ответ 5
Улучшая ответ 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 should be a hash
end