我正在构建一个应用程序,用于在计划中分配班次,有或没有关联的员工。也就是说,没有分配员工的Shift在计划中充当占位符。
在任何指定日期,我希望时间表显示该日期的所有班次(连续订购),然后显示未安排在该日期工作的所有剩余员工。
以下是模型:
class Employee < ActiveRecord::Base
belongs_to :account
has_many :shifts
end
class Shift < ActiveRecord::Base
belongs_to :account
belongs_to :employee
default_scope order(:starts_at)
end
和我有问题的,可怕的控制器代码(为了简洁而略微编辑):
class SchedulesController < ApplicationController
include CurrentDateHelper
def day
@shifts = @account.shifts.includes(:employee).within(current_date_range).all
@employees = @account.employees.alphabetically.all
@employees.reject!{|employee| @shifts.map(&:employee).include? employee}
end
end
和(非常简化)视图:
<tbody>
<%- @shifts.each do |shift| -%>
<%- if shift.employee.present? -%>
<%- employee = shift.employee -%>
<%- employee_shifts = shifts.select{|s| s.employee == employee} -%>
<tr>
<th><%= employee.name %></th>
<%- employee_shifts.each do |shift| -%>
<td><%= shift.timestamp %></td>
<%- end -%>
</tr>
<%- else -%>
<tr>
<th>Unassigned</th>
<td><%= shift.timestamp %></td>
</tr>
<%- end -%>
<%- end -%>
<%- @employees.each do |shift| -%>
<tr>
<th><%= employee.name %></th>
<td>Click to create a shift for <%= employee.name %></td>
</tr>
<%- end -%>
</tbody>
我的问题是,如果/当员工在同一天有多个班次时,员工当前在计划中多次显示。 那,和控制器代码只是丑陋:S
我可能需要按员工对@shifts进行分组,并从那起工作......? 我的SQL排序不是那么好,所以任何指针都非常感激 - 我不一定在寻找复制/粘贴解决方案,更像是一些线索让我深入挖掘和学习。
感谢您阅读本文 - 我希望它有意义! :)
答案 0 :(得分:1)
你可能是正确的,你想按班次分组,但你可能不希望用SQL做到这一点。您确实希望在视图中访问该数据,并且如果您在SQL中按员工分组,则每个员工只返回一个班次。
相反,你可能想要使用可枚举的group_by
,它在视图中看起来像:
<% @shifts.group_by(&:employee).each do |employee, shifts| %>
<%# do stuff for each 'employee' the grouped array of his/her 'shifts' %>
<% end %>
至于其他部分。您可以排除随班次返回的员工的ID。查看Arel的'not_in'谓词来做到这一点,例如。
ids = @shifts.map {|s| s.employee.try(:id) }.compact
condition = Employee.arel_table[:id].not_in(ids)
@employees = @account.employees.alphabetically.where(condition)
# of if you extracted this into a scope 'exluding' on Employee, it could look like:
@employees = @account.employees.alphabetically.excluding(@shifts.map &:employee)
或者如果您只想替换正在进行的reject!
业务,您可以简单地从数组中减去转移持有用户。 e.g:
@employees = @account.employees.alphabetically.all - @shifts.map(&:employee)
答案 1 :(得分:0)
如果您想跳过sql,也可以根据员工ID执行uniq。