M. Suurland M. Suurland - 7 months ago 15
Ruby Question

How to use polymorphism to remove a switch statement which compares strings?

I am new to Ruby, so let me describe the context of my problem first:
I have a json as input which has the following key / value pair:

{
"service": "update"
}


The value has many different values for example: insert,delete etc.
Next there is a method x which handles the different requests:

def x(input)

case input[:service]
services = GenericService.new

when "update"
result = services.service(UpdateService.new,input)
when "insert"
result = services.service(InsertService.new,input)
when "delete"
result = services.service(DeleteService.new,input)
....
....
else
raise "Unknown service"
end
puts JSON.pretty_generate(result)
end


What is bordering me is that I still need to use a switch statement to check the String values (reminds me of instance of ugh). Is there a cleaner way (not need to use a switch)?

Finally I tried to search for an answer to my question and did not succeed, if however I missed it feel free to comment the related question.

Update: I was thinking to maybe cast the string to the related class name as follows: How do I create a class instance from a string name in ruby? and then call result = services.services(x.constantize.new,input) , then the class names ofcourse needs to match the input of the json.

Answer

You can try something like:

def x(input)

  service_class_name = "#{input[:service].capitalize}Service"
  service_class = Kernel.const_get(service_class_name)
  service_class.new(input).process

end

In addition you might want to check if this is a valid Service class name at all.

I don't understand why you want to pass the service to GenericService this seems strange. let the service do it's job.

Comments