Rails: Using Eval to call another action

2k Views Asked by At

I know calling other actions from the controller isn't approved, but code I've got is using eval() to do exactly that.

  if @payment.save
    eval("pay_with_#{params[:method]}")
  end 

the method parameter is set (its value is realex) and the payment is saving, yet the pay_with_realex function isn't being called. Is this presumably to do with eval()??

What would you suggest as an alternative?

3

There are 3 best solutions below

0
On

You could use Object.send

if @payment.save
    send("pay_with_#{params[:method]}")
end 
0
On

Without knowing more about your controller, my initial thought would be to move "pay_with_" methods down into whatever your @payment class is and subclass it to handle the different payment methods.

class Payment < ActiveRecord::Base

end

class PaymentRealEx < Payment
  def pay
    # your way of doing payment
  end
end

class PaymentController
  def create
    case params[:method]
    when "realex"
      @payment = PaymentReadEx.new
    end
    if @payment.save
      @payment.pay
    end
  end
end
0
On

You can call other methods in the controller dynamically but it's not a great idea for various reasons. You can have private controller methods and then call them based on the condition but then your code will not be Object Oriented.

But If you have to do this,

You can use Object#send

if @payment.save
    send("pay_with_#{params[:method]}")
end 

or you can use method.call

if @payment.save
    method("pay_with_#{params[:method]}").call
end

Having said this, the best way would be to have the pay method is models and call them based on your parameter, probably using STI.