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

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

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

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

Devise

Deviseとは、Ruby-on-Railsの認証機能を追加するプラグインです。

Haml

Haml(HTML abstraction markup language)は、HTML/XHTMLを効率的に記述するためのマークアップ言語および記法です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

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

Q&A

解決済

2回答

1429閲覧

ログインが出来ない。

yume0409

総合スコア45

Ruby on Rails 5

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

Devise

Deviseとは、Ruby-on-Railsの認証機能を追加するプラグインです。

Haml

Haml(HTML abstraction markup language)は、HTML/XHTMLを効率的に記述するためのマークアップ言語および記法です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

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

0グッド

0クリップ

投稿2020/02/19 11:06

編集2020/02/21 07:05

ログインを実装するのにdeviseを用いました。
ログインに失敗した時にエラーメッセージを出したいのでコントローラーをカスタマイズしました。
sessions_controller.rb

def new @user = User.new end def create @user = User.find_by(email: session_params[:email], encrypted_password: session_params[:encrypted_password]) if @user redirect_to :root else @error_message = "エラー" @email = params[:email] @encrypted_password = params[:encrypted_password] render "devise/sessions/new" end end private def session_params params.permit(:email, :encrypted_password) end end

sessions/new.html.haml

.xxx %h2 ログイン = form_for(user_session_path) do |f| - if @error_message .aaa = @error_message .eee = f.label :email %br/ = f.email_field :email, autofocus: true, autocomplete: "email", class: "bbb" .eee = f.label :password %br/ = f.password_field :password, autocomplete: "current-password", class: "ccc" - if devise_mapping.rememberable? .eee = f.check_box :remember_me = f.label :remember_me .nnn = f.submit "Log in", class: "ddd"

このようにするとログインボタン押した時にアドレスとパスワードは合っているのにエラーメッセージが出ます。
一度コントローラーをカスタマイズする前に戻すとちゃんとログイン出来ています。

そして、new.html.hamlの3行目を

= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|

に変えると(カスタマイズする前の記述)

ArgumentError in Users::Sessions#create First argument in form cannot contain nil or be empty

このエラーが出ます。

= form_for(user_session_path) do |f|

元の記述に戻してからログインすると何故かログイン出来ます。
でも、ログアウトしてまたログインすると出来なくなっています。
何日も悩んでいるので、ご教授頂けると嬉しいです…!
よろしくお願いします。

#補足
回答ありがとうございます。
親メソッドの呼び出しはよく分からなかったので、色々調べてみたのですが…

class A def new @user = User.new end end class B < A def create @user = User.find_by(email: session_params[:email], encrypted_password: session_params[:encrypted_password]) if @user redirect_to :root else @error_message = "エラーです" @email = params[:email] @encrypted_password = params[:encrypted_password] render "devise/sessions/new" end end end private def session_params params.permit(:email, :encrypted_password) end end

defの上にクラスを付け足しましたが、こういうことでしょうか?
こうするとエラーメッセージは出ず、ログインも出来ません…。

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

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

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

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

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

guest

回答2

0

ベストアンサー

前回の回答では納得していただけなかったようですので、
追記の意味も込めてもう少し詳しく回答しますね。
Deviseのログイン機構の元々の処理は以下のようになっています。

rb

1 # GET /resource/sign_in 2 def new 3 self.resource = resource_class.new(sign_in_params) 4 clean_up_passwords(resource) 5 yield resource if block_given? 6 respond_with(resource, serialize_options(resource)) 7 end 8 9 # POST /resource/sign_in 10 def create 11 self.resource = warden.authenticate!(auth_options) 12 set_flash_message!(:notice, :signed_in) 13 sign_in(resource_name, resource) 14 yield resource if block_given? 15 respond_with resource, location: after_sign_in_path_for(resource) 16 end

質問者さんのコードではこの元々の処理を完全に上書きしてしまっているので、
それはもう「Deviseを使ってログインしている」とは言えない状態なのです。

現在の状況を雑に説明すると、モデルはDeviseを使用しているが、
コントローラはDeviseを使用していないということになります。
なので(Divise使わないので予想ですが)モデルでバリデーションを行った時に
想定していない値が含まれていたり不足していたりすると思います。

アドレスとパスワードは合っているのにエラーメッセージが出ます。

まさにこれの原因がそれです。

Deviseのコントローラのカスタマイズとは、基本的には
「レコードを取り出して、ログイン処理をする」部分は元々の処理にやらせて、
それ以外の部分をカスタマイズするというものを指します。

なので「レコードを取り出して、ログイン処理をする」部分をDeviseの元々の処理で行うために
カスタマイズしたメソッド内で親クラスのメソッド呼び出しを行う必要があります。

投稿2020/02/21 00:45

編集2020/02/21 00:53
Mugheart

総合スコア2344

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

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

no1knows

2020/02/21 00:53

なるほど・・・そういう経緯があったのですね。 だから僕の回答に行き違いのようなコメントを頂いたわけですね。 ありがとうございます!
yume0409

2020/02/29 10:24

ご回答ありがとうございました。 私には難しすぎたので別の方法でエラーを出すようにしました。
guest

0

Deviseの動きをきちんと理解していないとカスタマイズするのは難しい気がします。
日本語表記するのなら、i18n(国際化対応)をしたほうが良いかもしれません。

Qiita deviseを日本語化する

追記

たぶんよくわからずに独学で進めて混乱していると思うので、一度、今作っているアプリの手をとめてDeviseの動きについて確認すると良いと思います。

ということで、おすすめしたいこと。
0. 新しいアプリ(rails new project-appコマンド)を作ります。
アプリを作る場所(ディレクトリ)は、今のアプリと同じ階層が良いと思います。
0. Deviseを設定します。
こちらに沿って導入:https://www.sejuku.net/blog/13378
「deviseに機能を追加する」の見出しの前まで設定
0. http://localhost:3000/users/sign_inを表示します。
0. 適当なユーザー名とパスワードを入力するとエラー「英語」が表示されます。(←これもDeviseの標準機能)

yume0409さんにとって大事なのは、2.の「こちらに沿って導入」です。
まず書いてあることをそのまま実行して下さい。もしうまくいかないかった場合に、やみくもにソースを変更するのではなく、何をやって、どういうエラーがでたのかを質問してください。
手順が正しければ、きちんと導入できるはずです。

で、上記を動かして、次の質問が、「英語のエラーを日本語に直したい」もしくは「途中まで設定したDeviseの設定をもとに戻す方法」とかになると思います。

投稿2020/02/19 23:33

編集2020/02/21 01:14
no1knows

総合スコア3365

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

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

yume0409

2020/02/20 05:36

回答ありがとうございます。 エラーメッセージ出すためにカスタマイズしています。 日本語表記はしています!
no1knows

2020/02/20 10:25

deviseを日本語化したら、ログインに失敗したときに「メールアドレスまたはパスワードが違います。」というエラーが出ます。 そういうエラーメッセージではないということでしょうか?
no1knows

2020/02/21 00:25

ちなみに上記であれば、deviseをi18n(国際化対応)すればエラー表記がでます。 もし出ないようであれば、application.html.erbやログインで利用しているhtmlコードを提示いただければと思います。
yume0409

2020/02/24 06:33

遅くなりましたが、ご回答ありがとうございます。 一度そちらの方法で試しましたが、ログイン時にエラーメッセージは表示されないのですが、それで大丈夫なのでしょうか? 新規登録だとメッセージは表示されます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問