Rails 4 - 按外部键

时间:2016-09-29 07:19:48

标签: ruby-on-rails

我知道这一定很简单,但我真的迷失了。

三种模式:工作,任务和操作,如下:

Job
has_many :tasks

Task
belongs_to :job
belongs_to :operation

Operation
has_many :jobs

Job有一个属性total_pieces,告诉我你需要多少件。 对于每个Job,您可以添加一些Tasks,它们可以属于不同的Operations(切割,钻孔等),并且对于每个任务,您都可以设置多个部分。 我事先并不知道单个Operations需要多少Job,但我需要在新Operation时提醒用户剩下的Task件数。插入1}}。

让我们举个例子:

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

我需要提醒用户他们仍然需要削减50件并钻80。 假设,如果我补充:

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

我需要提醒用户他们还需要弯曲80件。

到目前为止,我已经设法使用Operations为每个Job列出了各种map,但现在我需要总结Task的所有部分Operation中的Job类型相同,且仅适用于属于该Operations的{​​{1}}中的Tasks个。{/ p>

有没有办法使用Job执行此操作?或者我需要手动编写查询吗?

编辑:这是我目前设法修补的内容。

Job中的方法mapoperations_applied排队的Operations中的所有Tasks个用户提供了一个ID列表。
然后另一种方法Job为我提供了单pieces_remaining for(operation)的剩余部分 最后,在我需要的operation次观看中,我遍历所有Job打印全部operations_applied
我知道这不是特别优雅,但到目前为止它有效,任何想法改善这一点? 谢谢。

2 个答案:

答案 0 :(得分:0)

我假设你的查询需要以下变量,

<强>属性 任务: 件数, 工作: 名称, 操作: 名称

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

如果您需要任何解释,请发表评论。

答案 1 :(得分:0)

如果我没有误解,则无法使用map执行您想要执行的操作,因为地图始终适用于arr.size == arr.map {...}.size,您希望reduce阵列。

你能做的是这样的事情:

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

现在operation_pieces包含与相应索引的pieces进行操作的id之和。但我确信有一个更优雅的版本可以做到这一点;)

编辑:将代码示例更改为哈希

编辑:这是更优雅的版本:

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)类型的哈希值。

相关问题