Hello
I’m trying to DRY my code and I think It could be done even better. The following 2 functions are “before_save” callbacks that practically do the same thing, but on a different set of attributes.
Since the code is highly similar, I was wondering if someone could help me to refactor the code?
def normalize_budget
result = normalize_generic(self.budget)
self.budget_min = result[:min]
self.budget_max = result[:max]
self.budget = result[:display]
end
def normalize_size
result = normalize_generic(self.size)
self.size_min = result[:min]
self.size_max = result[:max]
self.size = result[:display]
end
Kind regards,
Axinte
def normalize(property)
result = normalize_generic(self.send(property))
self.send("#{property}_min=", result[:min])
self.send("#{property}_max=", result[:max])
self.send("#{property}=", result[:display])
end
object.normalize(:size)
object.normalize(:budget)
Hi,
try this:
def normalize
update_result("budget")
update_result("size")
end
def update_result(field_name)
result = normalize_generic(self.send(field_name))
eval("self.#{field_name}_min = result[:min]")
eval("self.#{field_name}_max = result[:max]")
eval("self.#{field_name} = result[:display]")
end
Thank you both for your feedback. Based on your suggestions, I’ve finally decided to implement it in the following way:
%w[size budget].each do |property|
define_method(“normalize_#{property}_range”) do |*args|
result = normalize_generic_range(self.send(property))
self.send(“#{property}_min=”, result[:min])
self.send(“#{property}_max=”, result[:max])
self.send(“#{property}=”, result[:display])
end
end
this code defines normalize_size_range and normalize_budget_range and updates both sets of attributes accordingly.
kind regards,
Axinte
Here's a better solution:
%w[size budget].each do |property|
class_eval %Q!
def normalize_#{property}_range
result = normalize_generic_range( self.#{property} )
self.#{property}_min = result[:min]
self.#{property}_max = result[:max]
self.#{property} = result[:display]
end
!
end
Mauricio,
Thank you again for your help. Is there any difference between your solution and mine?
Kind regards,
Axinte
Yes, you're defining and method and using send at every call, my
solution will generate a method with direct calls instead of sending
them.