# ruby code case when not so dry

Ruby code below seems to be not so dry. Can you please help me reduce the code.

self.value = case self.type
when 'fast'
Increment.first.max_hours * Incrementor.first.fast_completion_day
when 'super_fast'
Increment.first.max_hours * Incrementor.first.super_fast_completion_day
when 'ludicrous'
Increment.first.max_hours * Incrementor.first.ludicrous_completion_day
else
Increment.first.max_hours * Incrementor.first.budget_completion_day
end


I think we can use Ruby metaprogamming here to reduce the code. But I am not very good with ruby meta programming at the moment.

You can try:

day = case self.type
when 'fast'       then :fast_completion_day
when 'super_fast' then :super_fast_completion_day
when 'ludicrous'  then :ludicrous_completion_day
else                   :budget_completion_day
end

self.value = Increment.first.max_hours * Incrementor.first.send(day)


From a friend that knows more than me:

prefix = %w[ fast super_fast ludicrous ].include?(self.type) ? self.type : "budget"
self.value = Increment.first.max_hours * Incrementor.first.send(:"#{prefix}_completion_day")


This is probably about as short and dry as you can get it. That said, I'm not sure that this is more clear/easy to read. I'd probably add a method to Incrementor like Incrementor#completion_day_for(type) that would take care of this logic for you.

• Thank you so much @Martin. Hope this is just a start for me to write better codes. – Prabesh Shrestha Aug 19 '11 at 7:28