Gareth Burrows
Gareth Burrows

Reputation: 1182

Dynamic method call in Ruby

I am being passed a parameter from a form as per the following

area => "Time logs"
user_id => "21"

or

area => "Expense management"
user_id => "21"

This parameter is being used to determine which area of user data to purge from the system.

What I have in my controller is then

area = params[:area]
user = User.find(params[:user_id])

case area
when "Time logs"
  user.purge_time_log_data
when "Expense management"
  user.purge_expense_data
end

So the user supplies the area and the employee form the form, and then I purge the data for that area, by calling methods on the model. However, what I actually have in reality is perhaps ten areas, and I don't want a massive list in the controller. I cannot make the parameter match the method name, but is there a way I can do something like create a hash to translate the areas, such as

area_hash = {"Expense management" => "expense_data", "Time logs" => "time_log_data"}

and then call the method on the user model dynamically, so I just end up with 1 line in the controller. I'm guessing, but something like

employee.send("purge"+area_hash[area])

????

Upvotes: 0

Views: 117

Answers (1)

Thomas
Thomas

Reputation: 1633

You are close:

employee.send("purge_#{area_hash[area]}")

You should consider to use public_send to avoid to call private method without beeing aware:

employee.public_send("purge_#{area_hash[area]}")

Send use symbols so you might want to do this:

area_hash = {"Expense management" => :purge_expense_data, "Time logs" => :purge_time_log_data}
employee.public_send(area_hash[area])

Upvotes: 4

Related Questions