質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Heroku

HerokuはHeroku社が開発と運営を行っているPaaSの名称です。RubyやNode.js、Python、そしてJVMベース(Java、Scala、Clojureなど)の複数のプログラミング言語をサポートしている。

Twitter

Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

ログイン

ログインは、ユーザーがコンピューターシステムにアクセスするプロセスの事を呼びます。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

2回答

583閲覧

Twitterログイン機能を実装したいが、NoMethodError (undefined method `id' for "が出てしまう

takuya-mashimo

総合スコア5

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Heroku

HerokuはHeroku社が開発と運営を行っているPaaSの名称です。RubyやNode.js、Python、そしてJVMベース(Java、Scala、Clojureなど)の複数のプログラミング言語をサポートしている。

Twitter

Twitterは、140文字以内の「ツイート」と呼ばれる短文を投稿できるサービスです。Twitter上のほぼ全ての機能に対応するAPIが存在し、その関連サービスが多く公開されています。

ログイン

ログインは、ユーザーがコンピューターシステムにアクセスするプロセスの事を呼びます。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2020/01/10 15:28

編集2020/01/11 06:18

###実現したいこと
Twitter APIを使用したログイン機能を実装したい。
callbackが通って欲しい。

###ここに質問の内容を詳しく書いてください。
gem 'omniauth-twitter'を使用(deviseは使用してません)して、Ruby on railsでWebアプリを開発しています。

以下のリンクを踏んでログインします。
イメージ説明

また、許可を求める画面には遷移するのですが、callbackをする際に以下のエラーが出てしまいます。

NoMethodError (undefined method `id' for "1085900685269299200-twitter@example.com":String):app/controllers/sessions_controller.rb:10:in `create'

発生している問題・エラーメッセージ

herokulogs

12020-01-10T15:38:55.521220+00:00 app[web.1]: I, [2020-01-10T15:38:55.521099 #4] INFO -- : [2a9a85d8-ba86-4690-8f80-fd5b68e321ea] Processing by SessionsController#create as HTML 22020-01-10T15:38:55.521806+00:00 app[web.1]: I, [2020-01-10T15:38:55.521733 #4] INFO -- : [2a9a85d8-ba86-4690-8f80-fd5b68e321ea] Parameters: {"oauth_token"=>"h6Zl4wAAAAABBrtcAAABb5AbrwY", "oauth_verifier"=>"qs7ctVofKAniNYibNMfXeZW4VYDDxn86", "provider"=>"twitter"} 32020-01-10T15:38:55.525388+00:00 app[web.1]: I, [2020-01-10T15:38:55.525301 #4] INFO -- : [2a9a85d8-ba86-4690-8f80-fd5b68e321ea] Completed 500 Internal Server Error in 3ms (ActiveRecord: 0.0ms) 42020-01-10T15:38:55.526243+00:00 app[web.1]: F, [2020-01-10T15:38:55.526174 #4] FATAL -- : [2a9a85d8-ba86-4690-8f80-fd5b68e321ea] 52020-01-10T15:38:55.526392+00:00 app[web.1]: F, [2020-01-10T15:38:55.526317 #4] FATAL -- : [2a9a85d8-ba86-4690-8f80-fd5b68e321ea] NoMethodError (undefined method `id' for "1085900685269299200-twitter@example.com":String): 62020-01-10T15:38:55.526526+00:00 app[web.1]: F, [2020-01-10T15:38:55.526460 #4] FATAL -- : [2a9a85d8-ba86-4690-8f80-fd5b68e321ea] 72020-01-10T15:38:55.526666+00:00 app[web.1]: F, [2020-01-10T15:38:55.526572 #4] FATAL -- : [2a9a85d8-ba86-4690-8f80-fd5b68e321ea] app/controllers/sessions_controller.rb:10:in `create'

該当のソースコード

app/models/user.rb↓

usermodel

1class User < ApplicationRecord 2 validates :name, presence: true, length: { maximum: 50 }, unless: :uid? 3 validates :email, presence: true, length: { maximum: 255 }, 4 format: { with: /\A[\w+\-.]+@[a-z\d\-.]+.[a-z]+\z/i }, 5 uniqueness: { case_sensitive: false },unless: :uid? 6 7 has_secure_password nalidations: false 8 validates :password, presence: true, unless: :uid? 9 10 has_many :posts 11 12 def self.find_or_create_from_auth(auth) 13 provider = auth[:provider] 14 uid = auth[:uid] 15 name = auth[:info][:name] 16 email = User.dummy_email(auth) 17 18 # self.find_or_create_by(provider: provider, uid: uid) do |user| 19 # user.username = name 20 # end 21 end 22 23 def self.dummy_email(auth) 24 "#{auth.uid}-#{auth.provider}@example.com" 25 end 26end 27

sessions_controller.rb↓

sessionscontroller

1class SessionsController < ApplicationController 2 def new 3 end 4 5 def create 6 #omniauthを使ったログイン処理 7 auth = request.env['omniauth.auth'] 8 if auth.present? 9 user = User.find_or_create_from_auth(request.env['omniauth.auth']) 10 session[:user_id] = user.id 11 redirect_back_or user 12 else 13 #既存のログイン処理 14 #フォームデータのemailを小文字かして取得(downcase) 15 email = params[:session][:email].downcase 16 #フォームデータのpasswordを取得している 17 password = params[:session][:password] 18 #ログインが成功した時と失敗したときの分岐 19 if login(email, password) 20 flash[:success] = 'ログインに成功しました。' 21 redirect_to @user 22 else 23 flash.now[:danger] = 'ログインに失敗しました。' 24 render :new 25 end 26 end 27 end 28 29 def destroy 30 session[:user_id] = nil 31 flash[:success] = 'ログアウトしました。' 32 redirect_to root_url 33 end 34 35 private 36 37 def login(email, password) 38 #入力フォームで入力されたemailと持つuserを検索し、インスタンス変数に代入 39 @user = User.find_by(email: email) 40 #見つかる時と見つからない時で分岐させ、authenticateで@userのパスワードと合ってるか確認 41 if @user && @user.authenticate(password) 42 # ログインが成功した時(確認して正しい時) 43 session[:user_id] = @user.id 44 return true 45 else 46 # ログインに失敗した時(確認して正しくない時) 47 return false 48 end 49 end 50end 51

routes.rb

routes

1Rails.application.routes.draw do 2 root to: 'toppages#index' 3 4 get 'auth/:provider/callback', to: 'sessions#create' 5 6 get 'login', to: 'sessions#new' 7 post 'login', to: 'sessions#create' 8 delete 'logout', to: 'sessions#destroy' 9 10 get 'signup', to: 'users#new' 11 resources :users, only: %i(index show new create) 12 13 resources :posts, only: %i(create destroy) 14 15 # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html 16end

ルーティング

root_path GET / toppages#index GET /auth/:provider/callback(.:format) sessions#create login_path GET /login(.:format) sessions#new POST /login(.:format) sessions#create logout_path DELETE /logout(.:format) sessions#destroy signup_path GET /signup(.:format) users#new users_path GET /users(.:format) users#index POST /users(.:format) users#create new_user_path GET /users/new(.:format) users#new user_path GET /users/:id(.:format) users#show posts_path POST /posts(.:format) posts#create post_path DELETE /posts/:id(.:format) posts#destroy rails_service_blob_path GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show rails_blob_representation_path GET /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format)active_storage/representations#show rails_disk_service_path GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show update_rails_disk_service_path PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update rails_direct_uploads_path POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create

試したこと

herokuに環境変数を通し、emailがnillだと思いdummy_emailを作成する処理をuserモデルに追記しました。

しかし、変わらずにエラーが出てしまいます。

補足情報(FW/ツールのバージョンなど)

Ruby on rails
docker
macos Catalina 10.15.2
herokuでデプロイしています。

独学で勉強中の身のため、理解していないところが多々あるかもしれません。よろしくお願いします。

##参考サイト
[Rails]SNSアカウントログイン機能の実装かつ既存userモデルと衝突しない方法

RailsでいろんなSNSとOAuth連携/ログインする方法

RailsでTwitterログイン認証を実装

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

どっかの変数がnillだからそのエラーが出てるんですから、そのエラーが出る行のところの変数のナカミを全部チェックすればどーでしょう。

まずはなんでエラーが出てるのか、どこで出てるかを特定することです

投稿2020/01/10 23:03

y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takuya-mashimo

2020/01/11 15:02

その通りですね。。 これから、検証能力を高めるためにdebug方法や基礎の知識をより高めます! 回答ありがとうございました!
guest

0

ベストアンサー

undefined method `id' for "...":String) つまり文字列にidは定義されてないよというエラーです
user = User.find_or_create_from_auth といかにも User が戻ってきそうなmethod名ですが、見てみるとfind_or_create_from_auth(auth) の最後の行が
email = User.dummy_email(auth)
になっているので、メールアドレス(文字列)が 返って来てます。
ここはuserを返さないと。
コメント化してある

# self.find_or_create_by(provider: provider, uid: uid) do |user| # user.username = name # end

をきちんと実装しましょう

追記
見なおしてみると、質問のタイトルと内容に有るエラーメッセージがまるで違いますね。
正しい質問をしないと正しい答えは得られません

投稿2020/01/11 02:53

編集2020/01/11 02:55
winterboum

総合スコア23284

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

takuya-mashimo

2020/01/11 15:01

アドバイスありがとうございます。 編集した際に、タイトルの編集をし忘れていました。以後気をつけます。 新しい、問題が発生したので、それの解決に動きます。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問