mahi-man
mahi-man

Reputation: 4686

Rails chain multiple commands to send method with arguments

I am trying to chain a series of command together to the send method based on a string. So far I have this which works fine:

"visible_tasks.count".split('.').inject(user1, :send)

Which is the equivalent of:

user1.send("visible_tasks").send("count")

What I am struggling with is how to modify the split/inject so I can pass arguments to specific send methods. As an example I would like to be able to do the equivalent of:

user1.send("visible_tasks").send("find", 383)

I have tried many things along the lines of:

"visible_tasks.find 383".split('.').inject(user1, :send)
"visible_tasks.find, 383".split('.').inject(user1, :send)
"visible_tasks.find(383)".split('.').inject(user1, :send)

but it interprets everything after the "." as an entire method, not method + arguments.

Update: I ended up using the eval method as suggested below by @Leantraxxx I have only called within a safe_send method of white listed methods as follows:

def safe_send(method)
method_valid = false #initialise to false
VALID_USER_METHODS.each do |valid_user_method|
  if !/^#{valid_user_method}$/.match(method).nil? #if the method matches any of the valid_user_methods, retrn true and break the loop
    method_valid = true
    break
  end
end
raise ArgumentError, "#{method} not allowed" unless method_valid == true

eval method

end

Upvotes: 1

Views: 1363

Answers (1)

Leantraxxx
Leantraxxx

Reputation: 4596

You can use eval instead.

eval("Doctor.last.appointments.first")
=> #<Appointment id: 75, appointment_date: "2014-06-11", patient_id: 47, doctor_id: 5, created_at: "2014-12-23 18:55:13", updated_at: "2014-12-23 18:55:13", time_slot_id: 40, video_call_token: nil, call_state: "pending", payment_state: "unpaid", session_id: nil, manual_payment_at: nil, performed_video_call: false>

Upvotes: 1

Related Questions