2011-09-07 417 views
0

我有以下SQL代碼:需要幫助把一個SQL查詢到一個ActiveRecord查詢

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 

添加的圖像鏈接

Link to image

鏈路示出的曲線圖。我需要做的是將我的SQL語句轉換爲一個activeRecord查詢,它將像我提供的那樣將其顯示爲我的其他圖形。

+0

問題是什麼? – Daan

+0

我想將上面的SQL語句轉換爲RoR,以便當我將它實現爲高層圖時,它將顯示所有用戶他們的任務和他們的小時 – David

+0

爲此,您需要顯示ActiveRecord模型,因爲從中生成SQL。但是真正的問題是什麼?究竟是什麼錯誤?你需要更清楚一點.. – Daan

回答

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

我的建議是,爲什麼要你使用關聯名稱的急切加載?

+0

謝謝,但我需要它類似於這種格式,我編輯了你的答覆 – David

+0

看來@Djj想要一個小時的總和。我已經有麻煩試圖完全使用group()和average(),並最終使用'select(「average(model.field),name」)。group(「name」)''的方式工作,工作得很好。它會不會更容易? –

+0

請檢查我的帖子,因爲我已經進一步更新 – David

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") 
+0

'record = Effort.sum(:hours, :joins =>:project_task, :conditions => {「project_tasks。project_id「=> project.id, 」project_tasks.task_name「=> taskname}) projdata ['values'] .push(record) end'我需要它看起來類似於此,以便我可以然後推所有的數據返回到數組 – David

+0

然後你可以嘗試在鏈的末尾添加類似'.collect(&:hours)'的東西(參見http://www.ruby-doc.org/core/classes/Array。 (#)html#M000247 fo collect()usage) –

+0

不知道它是否有效,但你可能想試試這個: Effort.sum(:hours, :group => [:project_task_id,:user_id], :joins = > [:project_task,:user]) –

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