我有以下SQL代码:
SELECT u.full_name, pu.task_name, sum(hours)
FROM efforts
INNER JOIN project_tasks pu ON efforts.project_task_id = pu.id
INNER JOIN users u ON efforts.user_id = u.id
GROUP BY user_id, task_name
输出所有用户,他们的任务和工作时间。我现在要做的是将其转换为Rails的ActiveRecord查询。
我试图让它看起来与我在下面所做的相似,但似乎无法使我的逻辑正确。
Project.all.each do |project|
projdata = { 'name' => project.project_name.to_s,
'values' => [] }
['Pre-Sales','Project','Fault Fixing','Support'].each do |taskname|
record = Effort.sum( :hours,
:joins => :project_task,
:conditions => { "project_tasks.project_id" => project.id,
"project_tasks.task_name" => taskname } )
projdata[ 'values' ].push( record )
end
@data.push( projdata )
end
end
end
添加了图片链接
该链接说明了一个图表。我需要做的是将我的SQL语句转换为activeRecord查询,它将像我提供的其他图形一样显示它。
答案 0 :(得分:0)
SELECT u.full_name, pu.task_name, hours
FROM efforts
INNER JOIN project_tasks pu ON efforts.project_task_id = pu.id
INNER JOIN users u ON efforts.user_id = u.id
GROUP BY user_id, task_name
Effort.find(:all, :select => "users.full_name, project_tasks.task_name, hours", :joins => [:user, :project_task], :group => "users.user_id, project_tasks.task_name")
但是,我有一个疑问,你怎么能得到“小时”字段而不在分组部分添加它。所以,最好的是,您也可以在分组部分添加小时数。
但是,您应该在以下文件中进行一些其他更改
供应商/插件/ expandjoinquery / init.rb”
class ActiveRecord::Base
class << self
private
def add_joins!(sql, options, scope = :auto)
scope = scope(:find) if :auto == scope
join = (scope && scope[:joins]) || options[:joins]
sql << " #{expand_join_query(join)} " if join
end
def expand_join_query(*joins)
joins.flatten.map{|join|
case join
when Symbol
ref = reflections[join] or
raise ActiveRecord::ActiveRecordError, "Could not find the source association :#{join} in model #{self}"
case ref.macro
when :belongs_to
"INNER JOIN %s ON %s.%s = %s.%s" % [ref.table_name, ref.table_name, primary_key, table_name, ref.primary_key_name]
else
"INNER JOIN %s ON %s.%s = %s.%s" % [ref.table_name, ref.table_name, ref.primary_key_name, table_name, primary_key]
end
else
join.to_s
end
}.join(" ")
end
end
end
参考:http://snippets.dzone.com/posts/show/2119
我的建议是,为什么要使用带有关联名称的预先加载?。
答案 1 :(得分:0)
尝试类似:
Effort.joins(:project_tasks, :user).select("sum(hours) as total_hours, users.full_name, project_tasks.task_name").group("users.user_id, project_tasks.task_name")
答案 2 :(得分:0)
试试这个:
Effort.select(
"users.full_name full_name,
project_tasks.task_name task_name,
SUM(efforts.hours) total_hours").
joins(:project_task, :user).
group("users.user_id, users.full_name, project_tasks.task_name").map do |e|
puts e.full_name, e.task_name, e.total_hours
end