2016-09-29 3 views
1

これはシンプルでなければならないことはわかっていますが、私は本当に失われています。Rails 4 - 合計値は外部キーでグループ化されています

3つのモデル:ジョブ、タスクやオペレーション、次のように:

Job 
has_many :tasks 

Task 
belongs_to :job 
belongs_to :operation 

Operation 
has_many :jobs 

Jobはあなたが必要とするどのように多くの作品を私に伝え属性、total_piecesを、持っています。 それぞれJobの場合、異なるOperations(切断、穴あけなど)に属することができるTasksの数を追加することができます。また、すべてのタスクに対して多数の番号を設定することができます。 Jobにはどれくらいの数のOperationsが必要かわかりませんが、新しいTaskが挿入されたときには、その番号の数を知らせる必要があります。Operation私は、彼らはまだ50個をカットするために、私は追加した場合、80 仮にをドリルダウンする必要があるユーザーに警告する必要が

Job 1: total_pieces=100 
- Task 1: operation 1(cutting), pieces=20 
- Task 2: operation 1(cutting), pieces=30 
- Task 3: operation 2(drilling), pieces=20 

私たちは例を作ってみましょう

- Task 4: operation 3(bending), pieces=20 

彼らはまだ80個を曲げる必要があることをユーザーに警告する必要があります。

これまでのところ私はmapを使用して、各JobためOperationsのすべての種類を一覧表示するために管理してきましたが、今はJobに同じOperationタイプでTaskのすべての部分を合計する必要がある、とだけのものOperations存在についてそのJobに属するTasks

mapを使用してこれを行う方法はありますか?あるいは、私は手動でクエリを書く必要がありますか?

EDIT:これは私が現時点でパッチを当てたものです。仕事で

方法operations_appliedは私JobのためにキューイングTasks内のすべてのOperations USENDのIDのリストを与えます。
もう1つの方法pieces_remaining for(operation)は、残りの部分を私に返します。operation
最後に、私が必要としているJobのビューでは、すべてを反復します。operations_appliedすべてを印刷します。pieces_remaining_for
私はこれが特にエレガントではないことは分かっていますが、これまでのところこれを改善するためのアイデアはありますか? ありがとうございます。

答えて

0

マップが常にarr.size == arr.map {...}.sizeに適用され、reduceあなたの配列にしたいので私が誤解していない場合は、mapとしたいことをすることはできません。今operation_piecesは、各インデックスのidと操作のためのpiecesの合計が含まれてい

job = Jobs.first 

operation_pieces = {} 
job.tasks.each do |task| 
    operation_pieces[task.operation.id] ||= { operation: task.operation } 
    operation_pieces[task.operation.id][:pieces] ||= 0 
    operation_pieces[task.operation.id][:pieces] += task.pieces 
end 

:あなたは何ができるか

はこのようなものです。しかし、私はこれを行うにはよりエレガントなバージョンがあると確信している;)

EDIT:ハッシュへのコード例を変更し

EDIT:

job = Jobs.first 
job.tasks 
    .group_by(&:operation) 
    .map { |op, tasks| 
     { op => tasks.sum(&:pieces) } 
    } 

:ここには、よりエレガントなバージョンです。タスクの操作により、タスクのあなたの配列group_byグループが(多分あなたの代わりにgroup_by { |t| t.operation }を使用する必要がある、私はわからない)、その後map同じ操作で、各タスクのpieces内側にまとめています。最後に、タイプOPERATION => PIECES_SUM (INTEGER)のハッシュになります。

+0

ありがとう、これは私のパッチを当てた解決策よりもはるかに優れています! –

0

私は タスク属性

、クエリに必要な以下の変数を前提としています number_of_pieces、 仕事: 名、 操作: 名

Job.joins("LEFT JOIN tasks ON jobs.id = tasks.job_id").joins("LEFT JOIN operations ON operations.id = tasks.operation_id").select(" SUM(tasks.number_of_pieces) as number_of_pieces, operations.name, jobs.name").group("operations.id, jobs.id") 

これがすべて一覧表示されますがジョブ、およびその下の各操作に必要な個数の合計です。

あなたが操作や作品のリストが欲しいためJOB_IDを持っている場合は、以下のコードを使用し、

Job.find(params[:job_id]).joins("LEFT JOIN tasks ON jobs.id = tasks.job_id").joins("LEFT JOIN operations ON operations.id = tasks.operation_id").select(" SUM(tasks.number_of_pieces) as number_of_pieces, operations.name, jobs.name").group("operations.id, jobs.id") 

はあなたが必要な場合は、コメント内の任意の説明を入れてください。

+0

おかげで、私はSQLを使用しないように期待していた...私はそのために推測する問題 –

+0

で私のさらなるアプローチのための私の編集を参照してください、あなたは、データベースの構造をリファクタリングする必要があります。仕事と運営には関係がありません。 SQLクエリーを使わずにそれを達成することは不可能です。 –

関連する問題