我收到的AREL查询很痛苦。供参考(抱歉):
def self.summarize_user(user)
c = Arel::Table.new(:categories)
s = Arel::Table.new(:skills)
cp = Arel::Table.new(:completions)
query = c.project(c[:id], c[:name], c[:handle])
.project(s[:id].count.as("total_skills"))
.project(cp[:id].count.as("total_completed"))
.project(cp[:verified_on].count.as("total_verified"))
.join(s).on(s[:category_id].eq c[:id])
.join(cp, Arel::Nodes::OuterJoin).on(cp[:skill_id].eq s[:id])
.where(cp[:user_id].eq(user.id).or(cp[:user_id].eq nil))
.group(c[:id], c[:name], c[:handle])
# this is the relevant bit
connection.execute(query.to_sql)
end
这会执行并给出DB的正确结果,如下所示:
{ "id" => "13",
"name" => "Category 16",
"handle" => "category_16",
"total_skills" => "4",
"total_completed" => "0",
"total_verified" => "0"
}
所以,鉴于该方法已经是一个怪物,我宁愿不尝试通过结果.inject
将所有数字投射到Fixnum中。有没有办法在使用connection.execute
时将字段转换为正确的数据类型?
答案 0 :(得分:2)
您可以使用Virtus
class Summary
include Virtus.model
attribute :id, Integer
attribute :name, String
attribute :handle, String
attribute :total_skills, Integer
attribute :total_completed, Integer
attribute :total_verified, Integer
end
summary.map { |results| Summary.new(results) }
hsh = { "id" => "13",
"name" => "Category 16",
"handle" => "category_16",
"total_skills" => "4",
"total_completed" => "0",
"total_verified" => "0"
}
s = Summary.new(hsh)
s.total_skills # => 4
答案 1 :(得分:2)
您可以利用find_by_sql和to_json
json_records = Arel::Table.find_by_sql(query.to_sql).to_json
然后您可以提取结果,如
result = JSON.parse json_records
有几种方法可以将ActiveRecord
个对象转换为hash
。这只是我个人的偏好。
答案 2 :(得分:0)
def self.summarize_user(user)
# ... sins against nature ...
result = connection.execute(query.to_sql)
self.map_summary(result)
end
protected
def self.map_summary(summary)
summary.map do |result|
{
id: result['id'].to_i,
name: result['name'],
handle: result['handle'],
total_skills: result['total_skills'].to_i,
total_completed: result['total_completed'].to_i,
total_verified: result['total_verified'].to_i,
}
end
end