2015-12-22 104 views
1

我的數據庫中選擇子集有任務,其中有分配了涉及員工完成任務(除其他事項外)。用戶使條目,它始終有一個任務。我在入口創建代碼中發現一個錯誤,導致員工無法自動添加到作業列表中;我想編寫一個遷移程序,爲每個爲某項任務輸入條目並且沒有任何條目的員工創建分配。通過優雅的屬性

這是我目前的做法:

Task.all.each { |task| 
      assigned_employees = task.assignments.map(&:employee) 
      task.entries.select{ |entry| assigned_employees.exclude?(entry.employee) }.map(&:employee).uniq.each { |orphan_employee| 
       task.assignments.create(employee: orphan_employee, task: task) 
      } 
     } 

的選擇到MAP到uniq的是醜陋的。我可以更優雅地做到這一點嗎?值得注意的是:entry.employee是經歷另一個類的委託。

編輯:我想我會回來解決這個問題;一位高級程序員將此調用重寫爲使用連接和採摘。

回答

0

高級程序員改寫了這個查詢如下:

Task.find_each do |task| 
    assigned_employees = task.task_assignments.map(&:employee_id) 
    orphans = Timesheet.joins(:timesheet_entries). 
    where(timesheet_entries: { id: task.timesheet_entry_ids }). 
    where.not(timesheets: { employee_id: assigned_employees }). 
    pluck(:employee_id).uniq 

    puts "Found #{orphans.size} missing TaskAssignments for Task##{task.id}." if orphans.any? 

    orphans.each do |orphan_employee_id| 
    task.task_assignments.create(employee_id: orphan_employee_id, task: task) 
    end 
end 

值得注意:

  • find_each是更適合這個查詢比all.each,因爲它會運行在此查詢一次批量並保持系統性能。現在
  • 孤兒被分配給了,這使我們能夠提供在日誌中反饋的時候,我們用的地方,而不是選擇運行遷移
  • 使我們的查詢苗條
  • 我們可以用更簡潔pluck代替笨重的map(&:employee)