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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Devise

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

Ruby on Rails

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

Q&A

解決済

2回答

1064閲覧

Ruby on Rails ユーザー登録:sessionに入っているdeviseのpasswordを変数に代入できない。

frusciante

総合スコア8

Devise

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

Ruby on Rails

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

0グッド

0クリップ

投稿2020/02/08 12:21

編集2020/02/08 12:23

前提・実現したいこと

現在、Ruby on Railsで開発しており、ウィザード形式のユーザー登録フォーム実装をしております。
1ページ目で入力させたdeviseのpasswordの値がsessionには入るのですが、変数に代入する事ができません。
お手数ですが、ご助言いただけますと幸いでございます。
1ページ目のキャプチャ
2ページ目のキャプチャ

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

現状、登録フォームを入力していくと、最後のアクションで
Password can't be blank のエラーが表示されます。
エラー画面キャプチャ

該当のソースコード

  • registrations_controller.rb
# frozen_string_literal: true class Users::RegistrationsController < Devise::RegistrationsController before_action :configure_sign_up_params, only: [:performance] # before_action :configure_sign_up_params, only: [:create] # before_action :configure_account_update_params, only: [:update] # GET /resource/sign_up def new @user = User.new end def performance @user = User.new(sign_up_params) session["devise.regist_data"] = {user: @user.attributes} session["devise.regist_data"][:user]["password"] = params[:user][:password] # @user = User.new(session["devise.regist_data"]["user"]) # unless @user.valid? # flash.now[:alert] = @user.errors.full_messages # render :new and return # end end def done @user = User.new(session["devise.regist_data"]["user"]) # binding.pry session["devise.regist_data"] = {user: @user.attributes} session["devise.regist_data"][:user]["prefecture"] = params[:user][:prefecture] session["devise.regist_data"][:user]["introduction"] = params[:user][:introduction] session["devise.regist_data"][:user]["performance"] = params[:user][:performance] session["devise.regist_data"][:user]["portfolio"] = params[:user][:portfolio] @user = User.new(session["devise.regist_data"][:user]) @user.save! sign_in(:user, @user) end # POST /resource # def create # super # end # GET /resource/edit # def edit # super # end # PUT /resource # def update # super # end # DELETE /resource # def destroy # super # end # GET /resource/cancel # Forces the session data which is usually expired after sign # in to be expired now. This is useful if the user wants to # cancel oauth signing in/up in the middle of the process, # removing all OAuth session data. # def cancel # super # end # protected # If you have extra params to permit, append them to the sanitizer. def configure_sign_up_params devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute]) end # If you have extra params to permit, append them to the sanitizer. # def configure_account_update_params # devise_parameter_sanitizer.permit(:account_update, keys: [:attribute]) # end # The path used after sign up. # def after_sign_up_path_for(resource) # super(resource) # end # The path used after sign up for inactive accounts. # def after_inactive_sign_up_path_for(resource) # super(resource) # end end
  • application_controller.rb
class ApplicationController < ActionController::Base before_action :configure_permitted_parameters, if: :devise_controller? protected def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :name_kana, :tel, :birthday, :status, :prefecture, :introduction, :performance, :portfolio]) end end
  • user.rb
class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable validates :name, :name_kana, :tel, :birthday, :status ,presence: true validates :tel, uniqueness: true enum status: { 公開:1,非公開:2 }, _prefix: true enum prefecture: { 北海道:1,青森県:2,岩手県:3,宮城県:4,秋田県:5,山形県:6,福島県:7, 茨城県:8,栃木県:9,群馬県:10,埼玉県:11,千葉県:12,東京都:13,神奈川県:14, 新潟県:15,富山県:16,石川県:17,福井県:18,山梨県:19,長野県:20, 岐阜県:21,静岡県:22,愛知県:23,三重県:24, 滋賀県:25,京都府:26,大阪府:27,兵庫県:28,奈良県:29,和歌山県:30, 鳥取県:31,島根県:32,岡山県:33,広島県:34,山口県:35, 徳島県:36,香川県:37,愛媛県:38,高知県:39, 福岡県:40,佐賀県:41,長崎県:42,熊本県:43,大分県:44,宮崎県:45,鹿児島県:46,沖縄県:47, その他:99 }, _prefix: true end
  • new.html.haml
%h2 会員情報入力フォーム = form_for(@user, url: performance_path) do |f| = render "devise/shared/error_messages", resource: @user .name .name__title お名前(全角) .name__required 必須 = f.text_field :name, autofocus: true, autocomplete: "name", placeholder: "例)山田太郎" ,class: 'name-form' .name_kana .name_kana__title お名前カナ(全角) .name_kana__required 必須 = f.text_field :name_kana, autofocus: true, autocomplete: "name_kana", placeholder: "例)ヤマダタロウ" ,class: 'name_kana-form' .email .email__title メールアドレス .email__required 必須 = f.email_field :email, autocomplete: "email", placeholder: "PC・携帯どちらでも可" .password .password__title パスワード(半角英数字) .password__required 必須 = f.password_field :password, autocomplete: "new-password", placeholder: "6文字以上の半角英数字" .tel .tel__title 携帯電話の番号 .tel__required 必須 = f.text_field :tel, autofocus: true, autocomplete: "tel", placeholder: "携帯電話の番号を入力" .birthday .birthday__title 生年月日 .birthday__required 必須 .birthday__select-form != sprintf(f.date_select(:birthday, prefix:'user', with_css_classes:'XXXXX', prompt:"--", use_month_numbers:true, start_year:Time.now.year, end_year:1900, date_separator:'%s'),'年','月')+'日' .status .status__title 会員情報の公開設定 .status__required 必須 .status__select-form = f.select :status, User.statuses.keys, {promt: "---"} .actions = f.submit "次へ" -# = render "users/shared/links"
  • performance.html.haml
%h2 活動実績入力フォーム ※お仕事をご希望の方やクリエイターの方は、以下の項目(任意)をご入力ください。 %br ※会員登録のみ、または、お仕事のご依頼のみをご希望の方は何も入力せず、「会員登録する」のボタンをクリックしてください。 = form_for(@user, url: done_path) do |f| = render "devise/shared/error_messages", resource: @user .prefecture .prefecture__title 都道府県 .prefecture__select-form = f.select :prefecture, User.prefectures.keys, {promt: "---"} .introduction .introduction__title 自己紹介 = f.text_field :introduction, autofocus: true, autocomplete: "introduction", placeholder: "200文字程度で自己紹介文をご入力ください" ,class: 'introduction-form' .performance .performance__title 活動実績 = f.text_field :performance, autofocus: true, autocomplete: "performance", placeholder: "これまでの活動実績をご入力ください" ,class: 'performance-form' .portfolio .portfolio__title ポートフォリオなどの参考URL = f.url_field :portfolio, autofocus: true, autocomplete: "portfolio", placeholder: "" ,class: 'portfolio-form' .actions = f.submit "会員登録する" -# = render "users/shared/links"

試したこと

ユーザー登録、最後のアクションであるdoneアクションの最初の代入記述にbinding.pryをかけ、以下の値をターミナルで確認しました。
① @user ⇨ passwordが入っていない。
② session["devise.regist_data"]["user"] ⇨ passwordが入っている。
③ User.new(session["devise.regist_data"]["user"]) ⇨ passwordが入っていない。

def done @user = User.new(session["devise.regist_data"]["user"]) binding.pry session["devise.regist_data"] = {user: @user.attributes} session["devise.regist_data"][:user]["prefecture"] = params[:user][:prefecture] session["devise.regist_data"][:user]["introduction"] = params[:user][:introduction] session["devise.regist_data"][:user]["performance"] = params[:user][:performance] session["devise.regist_data"][:user]["portfolio"] = params[:user][:portfolio] @user = User.new(session["devise.regist_data"][:user]) @user.save! sign_in(:user, @user) end
仮説

doneアクションの前のperformanceアクションで
session["devise.regist_data"] = {user: @user.attributes}
を記述し、ハッシュを整形(?)した際にpasswordの値が session["devise.regist_data"] に入らないため、不具合が起きているのでしょうか?

※ただ、passwordを再代入する事でハッシュの中にpasswordが入るよう意図しております。
※下記記述は以前に別のアプリ開発で、ウィザード形式の実装を行った時のものですが、今回も同じ記述をそのまま書いております。

session["devise.regist_data"] = {user: @user.attributes} session["devise.regist_data"][:user]["password"] = params[:user][:password]

開発環境

ruby 2.5.1
Rails 5.2.4.1

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

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

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

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

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

guest

回答2

0

自己解決

解決方法(修正結果)

registrations_controller.rb
のdoneアクションを以下の記述に修正する事で解決し、ユーザー登録に成功しました。

def done session["devise.regist_data"]["user"]["prefecture"] = params[:user][:prefecture] session["devise.regist_data"]["user"]["introduction"] = params[:user][:introduction] session["devise.regist_data"]["user"]["performance"] = params[:user][:performance] session["devise.regist_data"]["user"]["portfolio"] = params[:user][:portfolio] @user = User.new(session["devise.regist_data"]["user"]) @user.save! sign_in(:user, @user) end

エラーの原因と修正箇所

@user = User.new(session["devise.regist_data"]["user"])
の記述で@userにpasswordの値が入らない問題と、その他発生したエラーについて、仮説を含みますが、下記2点が原因でした。

① session["devise.regist_data"] = {user: @user.attributes}の記述によってpasswordの値がsessionに入らなくなっていた。

こちらは、完全に理解はできていないので仮説ですが、上記、修正結果の記述でコメントアウトしている箇所が原因でした。
元々、doneアクションの前のperformanceアクションで記述していた
session["devise.regist_data"] = {user: @user.attributes}
をdoneアクションで再度記述した事により、passwordがsessionの中に入らなくなってしまったのだと思います。

②doneアクションのsessionのキーが文字列ではなくシンボルで書かれていた為、NoMethodErrorが表示され保存できなかった。

session記述にて「アクションをまたぐ事でキーがシンボルから文字列になる」という事を知らなかった為、キーをシンボルで記述していましたが、全て文字列で書くことにより、NoMethodErrorを解決できました。

投稿2020/02/08 19:20

編集2020/02/08 20:06
frusciante

総合スコア8

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

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

0

Deviseですとユーザ登録にはpasswordのほかに確認用passwordの入力エリアがあるはずです。それを削除すると登録できません。

エラー画面のparamsをみるとpasswordがありません。入力していますか?

なお、
コントローラーのcodeも載せてください

投稿2020/02/08 12:57

winterboum

総合スコア23567

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

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

frusciante

2020/02/08 14:15 編集

ありがとうございます!下記、状況を記載させていただきます! ======== ① コントローラーのcodeについて こちら、現在ユーザー新規登録で編集しているコントローラーは registrations_controller.rb application_controller.rb の2点なのですが、これ以外のファイルに記述が必要という事でしょうか? ※上記2点の記述内容は、質問内容の「該当のソースコード」の所に記載をしております。 ======== ② 確認用passwordについて こちら以前、別のアプリでステップ登録実装した際に、確認用の入力欄をhamlから削除しても登録はできたので、無くしております。 試しに、1ページ目の入力後に動くperformanceアクションで、ユーザー登録させる記述をコントローラー(registrations_controller.rb)に追記した所、ユーザー登録ができました。 ※1ページ目の入力内容だけでDB保存できるかというテストです。 ※コメントはマークダウン使用できないようなので、エディタのキャプチャを貼らせていただきます。 エディタキャプチャ:https://gyazo.com/b0e5bb9fcca62a4f77b2249f08d01438 ページ入力内容:https://gyazo.com/f9c4b29ed64680de07dccbe4156438fa DBキャプチャ:https://gyazo.com/df711c97e910efac6aa7f45772e1da42 ======== ③ エラー画面のpassword入力について こちら、入力自体はしており、session["devise.regist_data"]["user"]の中にも入力したpasswordの値は入っているのですが、doneアクションにて @user = User.new(session["devise.regist_data"]["user"]) で代入した際、@user にpasswordが入っていない状況となります。 ターミナルキャプチャ:https://gyazo.com/89dc7617ea272f2cc183ccdb46239837 ======== 以上、お手数ですが、ご確認のほどよろしくお願いいたします!
frusciante

2020/02/08 19:44

winterboum様 先ほど、自己解決の投稿をさせていただいたのですが、コントローラーの記述を修正する事で解決ができました! ご協力いただきまして誠にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問