You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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 method delete' 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 23:55:27