前提・実現したいこと
Ruby on Railsで残業時間を集計するシステムを制作しています。
このシステムの中のuserを一覧表示する表にて、現在月の各userの合計残業時間が多い順に表示されるようにしたいのですが、その方法がわからないので教えていただきたいです。
Userモデルの属性に応じた並び順の設定であれば、controllerにて例えば @users = User.all.order(created_at: :desc)
とすればよいのは分かるのですが、この度は関連するOvertime tableの集計結果にて応じて並び順を設定したく、その方法が分からずにいます。
お手数ですが、ご教示いただけると幸いです。
状況
該当のソースコード
index.html.erb
erb
1<p>今月の残業時間</p> 2 3<table class="table"> 4 <thead> 5 <tr> 6 <th>グループ名</th> 7 <th>氏名</th> 8 <th>現時点</th> 9 <th>月末(推計値)</th> 10 </tr> 11 </thead> 12 <tbody> 13 <% @users.each do |user| %> 14 <tr> 15 <td><%= user.group %></td> 16 <td><%= user.name %></td> 17 <td><%= @this_month_hour_data[user.id][:today] %></td> 18 <td><%= @this_month_hour_data[user.id][:end_of_month] %></td> 19 </tr> 20 <% end %> 21 </tbody> 22</table>
users_controller.rb
rb
1class UsersController < ApplicationController 2 def index 3 @users = User.all 4 5 @this_month_hour_data = Overtime.this_month_hour_data 6 end 7end
overtime.rb
rb
1class Overtime < ApplicationRecord 2 belongs_to :user 3 attr_accessor :work_time 4 before_validation :convert_work_time_to_work_time_minute 5 6 7 # {user_id: XX(分), ...} 8 def self.this_month_minute_data 9 this_month = Time.now.all_month 10 this_month_minute_data = Overtime.where(date: this_month).group(:user_id).sum(:work_time_minute) 11 end 12 13 def self.estimate_value_at_the_end_of_month(value) 14 today = Date.today 15 day_of_today = today.day 16 last_day_of_month = today.end_of_month.day 17 progress_rate = day_of_today.to_f / last_day_of_month 18 value / progress_rate 19 end 20 21 # {user_id: {today: XX(時間), end_of_month: XX(時間)}, ...} 22 def self.this_month_hour_data 23 this_month_hour_data = {} 24 Overtime.this_month_minute_data.each do |key, value| 25 hour_until_today = value.to_f / 60 26 this_month_hour_data[key] = {today: hour_until_today.floor(1), 27 end_of_month: Overtime.estimate_value_at_the_end_of_month(hour_until_today).floor(1)} 28 end 29 this_month_hour_data 30 end 31 32 33 private 34 35 def convert_work_time_to_work_time_minute 36 self.work_time_minute = Tod::TimeOfDay.parse(self.work_time).to_i / 60 37 end 38end
あなたの回答
tips
プレビュー