[英]Implement method_missing in Rails
我正在使用 OMDB API 来了解如何在 Rails 中使用 3rd Party api。 我已经设置了我的应用程序,所以我只需要输入电影标题,并且从 OMDB API 填充其他 6 个属性。 从 api 检索数据的所有方法调用都非常相似。 唯一改变的是方法名称中的一个单词和方法体中的一个单词。 这是一个这样的电话:
应用程序/服务/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
改变的是方法名称中get
之后的单词和parsed_response['Poster']
中的单词。 它们会根据我要恢复的属性而改变。
我以为我可以使用method_missing
来防止重复,但我没有成功。 这是我的method_missing
调用:
应用程序/服务/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
谁能看到我的method_missing
调用有什么问题?
首先,让我强调一下,这不一定是method_missing
的好用例,因为似乎没有办法获得不言自明的方法名称、参数等。 不过,我会尽量回答你的问题。
首先,你需要对API给你的东西采用你的方法命名,以减少参数的数量。 在您给出的示例中,您希望将方法调用更改为get_poster_by_t
因为poster
是 output 而t
是基于 URL 和您共享的响应的输入变量。
按照这个逻辑,您必须像这样编写缺少的方法:
def method_missing(method, *args)
if method =~ /\Aget_([^_]+)_by_([^_]+)\z/
response = HTTP.get("http://www.omdbapi.com/?#{$~[2]}=#{args[0]}&apikey=123456789").to_s
parsed_response = JSON.parse(response)
parsed_response[$~[1].capitalize]
end
end
那么你还应该合并 Ruby 的实现method_missing
的规则,即当你的规则不匹配时调用super
并覆盖respond_to_missing?
. 这会给你:
def method_missing(method, *args)
if method.to_s =~ /\Aget_([^_]+)_by_([^_]+)\z/
response = HTTP.get("http://www.omdbapi.com/?#{$~[2]}=#{args[0]}&apikey=123456789").to_s
parsed_response = JSON.parse(response)
parsed_response[$~[1].capitalize]
else
super
end
end
def respond_to_missing?(method, *args)
method.to_s =~ /\Aget_([^_]+)_by_([^_]+)\z/ || super
end
就个人而言,我不会在这里使用method_missing
,而是使用 go 和一个富有表现力的方法调用——像这样:
def get_field_by_param(field:, param:, value:)
response = HTTP.get("http://www.omdbapi.com/?#{param}=#{value}&apikey=123456789").to_s
parsed_response = JSON.parse(response)
parsed_response[field]
end
然后,您可以执行get_field_by_param(field: "Poster", param: :t, value: "Whatever")
类的操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.