这个选择/地图可以更具可读性吗?

时间:2014-03-05 15:37:05

标签: ruby-on-rails ruby refactoring

我有一个来自ActiveRecord的对象数组,我正在运行selectmap以获取一些值:

@jobs.select{|u| u[:user_id] == user.id}.map{|t| t[:regular_time]}.sum

有更可读的方法吗?

map变量的变化会有很多变化,如下所示:

@jobs.select{|u| u[:user_id] == user.id}.map{|t| t[:ot_time]}.sum
@jobs.select{|u| u[:user_id] == user.id}.map{|t| t[:vacation_time]}.sum
@jobs.select{|u| u[:user_id] == user.id}.map{|t| t[:holiday]}.sum

这样做的原因是我已经在单个查询中加载了数据,然后我将其分解为用户,然后将每个用户的各种数据分开。

真的这样做是为了避免数以千计的数据库调用。

3 个答案:

答案 0 :(得分:2)

我认为您的代码很好。如果你想要你仍然可以使用lambda分割它:

right_user = -> u {u[:user_id] == user.id } #creating a lambda
@jobs.select(&right_user).map(&:regular_time).sum

请注意

right_user = -> u {u[:user_id] == user.id } #creating a lambda

完全等同于

right_user = lambda { |u| u[:user_id] == user.id } #creating a lambda

答案 1 :(得分:2)

我会使用group_byuser_id对作业进行分组:

@jobs_by_user = @jobs.group_by(&:user_id)

并用以下内容计算总和:

@jobs_by_user[user.id].sum(&:ot_time)
@jobs_by_user[user.id].sum(&:vacation_time)
@jobs_by_user[user.id].sum(&:holiday)

答案 2 :(得分:0)

看起来用户有很多工作。如果是这样,那么你可以使用活动记录

user.jobs.sum(:regular_time)
user.jobs.sum(:ot_time)
....

如果您不想使用活动记录(如果您的项目已经加载,请避免数据库查询),那么您所能做的就是已经在评论中提到过。我喜欢使用.map(&:attribute_name).sum