使用Flickr Gem通过用户名获取用户ID调用API遇错求助
问题描述
我正在开发一个调用Flickr API展示照片的小型应用,使用flickr gem做认证。目前展示最新照片、按标签搜索照片的功能都正常,原本按user_id获取照片也能正常运行,但为了提升用户友好性(Flickr用户名比ID更容易查找),改成接收用户名,计划通过flickr.people.findByUsername方法获取用户ID,再用该ID调取照片。
修改的代码
表单代码
<div class="form"> <%= form_with url: :root, method: :get do |form| %> <%= form.text_field :username, placeholder: "Username", class: "form-field" %> <%= form.text_field :tags, placeholder: "tags", class: "form-field" %> <%= form.submit 'submit', class: "submit-btn" %> <% end %> </div>
控制器代码
class StaticPagesController < ApplicationController require "flickr" def index @flickr = Flickr.new if params[:username].present? user_id = @flickr.people.findByUsername username: params[:username] @photos = @flickr.people.getPhotos user_id elsif params[:tags].present? @photos = @flickr.photos.search tags: params[:tags], safesearch: 1 else @photos = @flickr.photos.getRecent end end end
遇到的错误
输入用户名后出现报错:
undefined method `delete' for {"id"=>"132822455@N05","nsid"=>"132822455@N05", "username"=>"images@twiston"}:Flickr::Response
提取代码(第8行附近):if params[:username].present? user_id = @flickr.people.findByUsername username: params[:username] @photos = @flickr.people.getPhotos user_id elsif params[:tags].present? @photos = @flickr.photos.search tags: params[:tags], safesearch: 1 else
Rails服务器内的错误信息:
oauth_args = args.delete(:oauth) || {}
尝试提取nsid传入API调用,但均失败:
- 修改为
@photos = @flickr.people.getPhotos user_id["nsid"],报错:no implicit conversion of Symbol into String - 修改为
@photos = @flickr.people.getPhotos user_id[:nsid],报错:undefined methoddelete' for nil:NilClass` - 修改为
@photos = @flickr.people.getPhotos user_id.nsid,报错:no implicit conversion of Symbol into String
已验证user_id["nsid"]能输出正确的nsid字符串,但错误仍未解决。
附initializers/flickr.rb文件:
require "dotenv/load" require "flickr" flickr_api_key = ENV["FLICKR_API_KEY"] flickr_shared_secret = ENV["FLICKR_SHARED_SECRET"] flickr = Flickr.new flickr_api_key, flickr_shared_secret # Flickr用户授权后跳转的URL @callback_url = "http://localhost:3000/auth_controller/callback" # 用户获取Flickr授权链接的方法 def auth flickr = Flickr.new API_KEY, SHARED_SECRET token = flickr.get_request_token(oauth_callback: URI.escape(@callback_url)) # 需要把token存储起来,用于用户跳转回回调方法时使用 # 我一般用会话键作为缓存键存在memcache里 @auth_url = flickr.get_authorize_url(token["oauth_token"], perms: "delete") # 在模板里把@auth_url作为链接给用户点击 end # 用户从Flickr跳转回来的回调方法 def callback flickr = Flickr.new request_token = # 从缓存或会话中取出之前存储的token oauth_token = params[:oauth_token] oauth_verifier = params[:oauth_verifier] raw_token = flickr.get_access_token( request_token["oauth_token"], request_token["oauth_token_secret"], oauth_verifier ) # raw_token是类似这样的哈希:{"user_nsid"=>"92023420%40N00", "oauth_token_secret"=>"XXXXXX", "username"=>"boncey", "fullname"=>"Darren%20Greaves", "oauth_token"=>"XXXXXX"} # 需要对nsid和名称参数使用URI.unescape解码 oauth_token = raw_token["oauth_token"] oauth_token_secret = raw_token["oauth_token_secret"] # 把oauth_token和oauth_token_secret存在会话或数据库中 # 在调用需要认证的方法前,把它们附加到Flickr实例上 # 将令牌附加到flickr实例,现在可以用这个对象进行认证后的调用了 flickr.access_token = oauth_token flickr.access_secret = oauth_token_secret end
解决方案
问题出在flickr.people.getPhotos的参数传递方式上——这个方法需要接收键值对形式的参数哈希,而不是直接传入nsid字符串。
正确的写法是把nsid作为user_id键的值传入:
if params[:username].present? user_info = @flickr.people.findByUsername username: params[:username] @photos = @flickr.people.getPhotos user_id: user_info["nsid"] # ... 其余代码保持不变
原因解释
- 最初直接传入
Flickr::Response对象时,gem会把整个对象当作参数哈希处理,尝试调用delete方法(用于提取oauth参数),但Flickr::Response并没有这个方法,因此报错。 - 后来直接传字符串
user_id["nsid"]时,gem会把这个字符串当作参数哈希的键,尝试处理符号键时出现类型转换错误。 - 必须明确传递
user_id: 具体nsid值的哈希参数,才能符合flickr gem的方法调用规范。
另外,建议在控制器初始化Flickr实例时,直接传入API密钥和密钥,避免未授权问题:
@flickr = Flickr.new(ENV["FLICKR_API_KEY"], ENV["FLICKR_SHARED_SECRET"])
内容的提问来源于stack exchange,提问作者DebakeDSP94
相关产品推荐
相关产品推荐

