Я работаю над небольшим приложением для доступа к Flickr API и размещения фотографий. Я использую гем flickr для авторизации. Это работает для последних фотографий, которые отображаются, если в форму еще ничего не введено. Работает поиск по тегам. Он работал с user_id, но я пытаюсь изменить его, чтобы принять имя пользователя, а затем использовать метод flickr.people.findByUsername, чтобы получить идентификатор пользователя, а затем использовать его для загрузки фотографий. На веб-сайте flickr легко найти имена пользователей, но трудно найти идентификаторы, поэтому я думаю, что это будет более удобно для пользователя. Вот текущая версия приложения до того, как я разветвил ее, чтобы попытаться это сделать. https://flickr-photo-feed.herokuapp.com/ Это очень простое приложение без модели и базы данных. Есть только действие контроллера индекса и очень простой партиал формы и еще один партиал для рендеринга возвращенных фотографий.
Я изменил форму, чтобы принять имя пользователя
<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
Если я ввожу имя пользователя, я получаю эту ошибку:
неопределенный метод `удалить' для {"id"=>"132822455@N05","nsid"=>"132822455@N05", "username"=>"images@twiston"}:Flickr::Response Извлеченный источник (вокруг строки №8): 6 7 8 9 10 11
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. Я не совсем понимаю ошибку отсутствия метода для удаления, но я понимаю, что она исходит от драгоценного камня flickr. Итак, я полагаю, что мне нужно вытащить nsid из хэша и передать его моему вызову API. Итак, я меняю одну строку на:
@photos = @flickr.people.getPhotos user_id["nsid"]
который генерирует эту ошибку:
нет неявного преобразования Symbol в String
Итак, я пробую это:
@photos = @flickr.people.getPhotos user_id[:nsid]
который дает мне эту ошибку:
неопределенный метод `удалить' для nil:NilClass
Я даже пробовал это:
@photos = @flickr.people.getPhotos user_id.nsid
что дает мне эту ошибку:
нет неявного преобразования Symbol в String
Я также пробовал несколько других вещей, но результатом всегда было одно из этих сообщений об ошибке. может ли кто-нибудь указать, где я ошибаюсь? Спасибо.
Обновлено: мне удалось убедиться, что я могу поместить user_id["nsid"] и правильный nsid выводится на сервер rails. Однако я все еще получаю сообщение об ошибке «нет неявного преобразования символа в строку». Итак, я попытался сохранить его в переменной и явно вызвать для него .to_str, прежде чем передать его методу @flickr.people.getPhotos. Я проверил с помощью p (не ставит), что он выводит в виде строки. "" появляются вокруг него. Однако эта конкретная ошибка сохраняется.
Отредактируйте, чтобы добавить файл 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
# This is the URL Flickr will redirect your users to once they agree to access
@callback_url = "http://localhost:3000/auth_controller/callback"
# Users should hit this method to get the link which sends them to flickr
def auth
flickr = Flickr.new API_KEY, SHARED_SECRET
token = flickr.get_request_token(oauth_callback: URI.escape(@callback_url))
# You'll need to store the token somewhere for when the user is returned to the callback method
# I stick mine in memcache with their session key as the cache key
@auth_url = flickr.get_authorize_url(token["oauth_token"], perms: "delete")
# Stick @auth_url in your template for users to click
end
# Your users browser will be redirected here from Flickr (see @callback_url above)
def callback
flickr = Flickr.new
request_token = # Retrieve from cache or session etc - see above
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 is a hash like this {"user_nsid"=>"92023420%40N00", "oauth_token_secret"=>"XXXXXX", "username"=>"boncey", "fullname"=>"Darren%20Greaves", "oauth_token"=>"XXXXXX"}
# Use URI.unescape on the nsid and name parameters
oauth_token = raw_token["oauth_token"]
oauth_token_secret = raw_token["oauth_token_secret"]
# Store the oauth_token and oauth_token_secret in session or database
# and attach to a Flickr instance before calling any methods requiring authentication
# Attach the tokens to your flickr instance - you can now make authenticated calls with the flickr object
flickr.access_token = oauth_token
flickr.access_secret = oauth_token_secret
end
Он есть в документации API flickr. Драгоценный камень просто обрабатывает аутентификацию (я думаю) и позволяет вам использовать методы API flickr. flickr.com/services/api/flickr.people.findByUsername.html.
Глядя на полезную нагрузку с помощью обозревателя API, я вижу method=flickr.people.findByUsername&magic_cookie=234b3965a506258b27e290d9884390067ae509406db656daa6ba05d0f81124b7¶m_api_key=&enable_username=on¶m_username=images%40twiston&format=json-nc&sign_call=full
Используя их проводник API, я вижу параметры запроса как: method: flickr.people.findByUsername magic_cookie: 234b3965a506258b27e290d9884390067ae509406db656daa6ba05d0f81124b7 param_api_key: enable_username: on param_username: images%40twiston format: json-nc sign_call: full
Не уверен насчет enable_username: on
, но похоже, что так и должно быть param_username: images%40twiston
. При использовании вашего нового кода полезная нагрузка автоматически преобразует username
в param_username
?
Документация невелика, но похоже, что так и должно быть:
flickr = Flickr.new "api key", "api secret"
@user = flickr.people.findByUsername username: 'images@twiston'
#=> {"id"=>"132822455@N05", "nsid"=>"132822455@N05", "username"=>"images@twiston"}
Что дает вам:
@user['nsid']
#=> "132822455@N05"
@user['id']
#=> "132822455@N05"
Итак, ваш код должен быть примерно таким:
@user = @flickr.people.findByUsername username: params[:username]
@photos = @flickr.people.getPhotos user_id: @user['id']
Метод findByUsername
возвращает этот хеш, а вы обрабатывали его так, как будто он возвращает только :id.
Документы говорят: В качестве альтернативы, если ключ API и общий секрет не предоставлены, Flickr попытается прочитать их из переменных среды:
ENV['FLICKR_API_KEY']
ENV['FLICKR_SHARED_SECRET']
Вы можете использовать консоль для ручной аутентификации с ключом и секретом в моем примере, чтобы убедиться, что он работает правильно.
Oauth обрабатывается файлом flickr.rb в инициализаторах, поэтому при запуске приложения об аутентификации позаботятся. Приложение отлично работает в своей первоначальной форме, где был поиск по user_id или тегам. Я попытаюсь использовать переменную экземпляра вместо локальной переменной, как вы это сделали. Большое спасибо, что взглянули на это. По сути, это единственный код, которым я не поделился. Добавлю в исходный пост.
Проблема не в экземпляре и локальной переменной. Это то, что вы возвращали объект ответа, доступ к которому осуществляется в хеш-форме. Если бы объект ответа был просто {user_id: 'xxxxx'}
, то он работал бы в исходной форме, потому что метод .people.getPhotos
принимает хэш. Но поиск пользователя возвращает хэш с тремя парами ключ/значение, поэтому вам нужно указать, какую из них использовать.
Еще одна странная вещь, которую я обнаружил: я попытался найти свою учетную запись по имени пользователя, и он говорит, что не найден. Но я могу найти себя по электронной почте или идентификатору, и в ответе отображается мое имя пользователя, но он все равно отказывается найти меня по имени. У меня есть очень старая учетная запись, которая была объединена с моей учетной записью Yahoo.
Спасибо, что разъяснили это. Я не мог понять, почему переменная экземпляра может иметь значение. Если вы посмотрите на мое редактирование ранее, вы увидите, что теперь я указываю ['nsid"] и могу использовать p для вывода этого в виде строки на вывод сервера rails. В основном я получаю то, что хочу, обратно в ответ, и я могу получить к нему доступ, но я не могу правильно отправить его в запросе фотографий по user_id.
Похоже, вы все еще делаете: @photos = @flickr.people.getPhotos user_id["nsid"]
? В метод нужно передать хэш: @photos = @flickr.people.getPhotos user_id: user_id["nsid"]
Я думаю, вы, возможно, только что взломали его. Я попробую это утром и обязательно дам вам знать, как это происходит. Не могу передать, как я ценю то, что ты смотришь на это.
response = @flickr.people.findByUsername username: params[:username]
@photos = @flickr.people.getPhotos user_id: response["nsid"]
Beartech был прав. Это сработало сразу.
Если мой ответ был правильным, вы можете нажать кнопку «принять», чтобы принять его как ответ? Это обычная практика, а не добавление ответа, который повторяет решение.
Где документация для
.findByUsername
? Я не вижу его нигде в коде драгоценного камня на github.