I'm using the OMDB API to learn about using 3rd Party apis in Rails. I've setup my app so all I have to input is the movie title and 6 other attributes get populated from the OMDB API. All of the method calls to retrieve the data from the api are very similar. The only thing that changes is one word in the method name and one word in the method body. Here is one such call:
app/services/omdb_service.rb
def get_image_by_title(title)
response = HTTP.get("http://www.omdbapi.com/?t=#{title}&apikey=123456789").to_s
parsed_response = JSON.parse(response)
parsed_response['Poster']
end
The things that change are the word after get in the method name and the word in the parsed_response['Poster']. They will change depending on what attribute I'm trying to get back.
I thought I could use method_missing to prevent duplication, but I'm having no success with it. Here is my method_missing call:
app/services/omdb_service.rb
def method_missing(method, *args)
if method.to_s.end_with?('_by_title')
define_method(method) do | args |
response = HTTP.get("http://www.omdbapi.com/?t=#{args[0]}&apikey=123456789").to_s
parsed_response = JSON.parse(response)
parsed_response['args[1]']
end
end
end
Can anyone see what is wrong with my method_missing call?
First of all, let me stress that this isn't necessarily a good use case for
method_missingbecause there doesn't seem to be a way to get self-explanatory method names, parameters and such. Nevertheless, I'll try to answer your question as best as I can.First of all, you need to adopt your method naming to the things that the API gives you to reduce the number of parameters. In the example you've given, you'd want to change the method call to
get_poster_by_tbecauseposteris the output andtis the input variable based on the URL and response you've shared.Following this logic, you'd have to write method missing like so:
Then you should also incorporate Ruby's rules for implementing
method_missing, namely callingsuperwhen your rule doesn't match and also overridingrespond_to_missing?. This then gives you:Also see https://makandracards.com/makandra/9821-when-overriding-method_missing-remember-to-override-respond_to_missing-as-well.
Personally, I'd not use
method_missinghere but instead go with an expressive method call – something like this:You can then do things like
get_field_by_param(field: "Poster", param: :t, value: "Whatever").