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

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

ただいまの
回答率

88.60%

ParameterMissingErrorの解決策をお願いします!!

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 464

r_hara

score 4

ウィザードフォーム形式の新規登録画面の実装です。最後の入力画面の送信ボタンでまとめてUsersテーブルとAddressesテーブルに入力内容を保存したいです。

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

ActionController::ParameterMissing in Users::RegistrationsController#create
  param is missing or the value is empty: user
/users/registrations_controller.rb


class Users::RegistrationsController < Devise::RegistrationsController
  before_action :user_params, only: [:create]

  def step_1
    @user = User.new
  end

  def step_2
    session[:user_params] = user_params
  end

  def step_3
    @user = User.new
    @user.build_address
  end

  def create
    @user = User.new(session[:user_params])
    @user.build_address
    if @user.save
      redirect_to payment_methods_path
    else
      render :user_information
    end
  end


  private

  def user_params
    params.require(:user).permit(
        :nickname,
        :email,
        :password,
        :password_confirmation,
        address_attributes: [:id, :last_name, :first_name, :last_name_kana, :first_name_kana,
                             :postal_code, :prefecture, :city, :address, :building_name, :phone_number])
  end
end


このstep_3でcreateアクションを実行しようとした際にエラーが出ます。

/users/registrations/step_3

= form_with model: @user, url: '/users', method: :post,  local: true do |f|
  = fields_for :address do |a|
    = a.text_field :last_name
    = a.text_field :first_name

    = a.text_field :last_name_kana
    = a.text_field :first_name_kana

    = a.text_field :postal_code

    = a.select :prefecture, Address.prefectures.keys, {}

    = a.text_field :city

    = a.text_field :address

    = a.text_field :building_name

    = a.telephone_field :phone_number

    = f.submit

試したこと

binding.pryで色々中身など確認しつつみていったところコントローラーのcreateアクション内の二行目の@user.build_addressで@userが上書きされてしまってるのではないかと思っています。
ただこの記述方法で作成されていた方の記事をほぼ丸パクリで書いたのですがなぜかエラーになってしまいました。
これ以上冗長になると返っていやかと思ったので他の箇所のコードは載せていないので解決に必要ならば載せますのでよろしくお願いします。

補足情報

ruby 2.5.1

Rails 5.2.3

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • winterboum

    2019/10/08 19:27

    エラーが起きたのは
    @user = User.new(session[:user_params])
    @user.build_address
    if @user.save
    のどの行ですか?

    あと、
    @user.build_address
    のcodeを見せて下さい

    キャンセル

  • r_hara

    2019/10/09 12:45 編集

    返事が遅くなりすみません。
    中身を確認したところ@user = User.new(session[:user_params])までは値が入っているのですが、次の行でsessionで受け取った@userの中身がなくなっているみたいなんですよね。

    エラーが出た箇所はrequire(:user)の引数userです。
    def user_params
    params.require(:user).permit(:nickname, :email, :password, :password_confirmation,
    address_attributes: [:id, :last_name, :first_name, :last_name_kana, :first_name_kana,
    :postal_code, :prefecture, :city, :address, :building_name, :phone_number])
    end

    @user.build_addressのコードとは下記のことでしょうか?
    class User < ApplicationRecord

    has_one :address
    accepts_nested_attributes_for :address
    ```

    キャンセル

回答 2

checkベストアンサー

+1

未検証ですが、View側の問題だと思います。

= form_with model: @user, url: '/users', method: :post,  local: true do |f|
  = f.fields_for :address do |a|


のようにf.fields_forとしないと{ "user" => { "address_attributes" => { ... } } }のようなパラメータが送信されないのでは?

もしくは

= form_with model: @user, url: '/users', method: :post,  local: true do |f|
  = fields model: :address do |a|


ですかね、うまくいけばいいんですが。

追記

user_paramsの中身はcreate内で使われていないのにbefore_actionで実行されていますね。
質問箇所とは違うのでこれ以上詳しく見る気は無いですが、見直しは必要だと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/10 15:53

    回答ありがとうございます!
    おっしゃる通りでした。
    fileds_forの最初にfをつけることにより解決致しまし。
    本当にありがとうございました!!

    キャンセル

+1

とりあえず、エラーを回避するだけならば

  before_action :user_params, only: [:create]

この行を削除

問題はこれを訂正したところで意図通りに動くようには見えないことです。

おそらくですが、

  def create
    @user = User.new(session[:user_params])
    @user.build_address

の、build_addressには引数が必要か
もしくはstep1で住所も入力済みだというのならば@user.build_addressは不要という事になります。


追記

自信はないが

def address_params
  params.require(:address).permit(:last_name, :first_name, :last_name_kana,
    :first_name_kana, :postal_code, :prefecture, :city,
    :address, :building_name, :phone_number)
end
@user.build_address(address_params)

うーん・・・ボツにして書き直したくなりますが、、、とりあえず動くかなとは思います。
(view側間違えてるような気がしています)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/09 12:50

    せっかく回答してくださったのに返事が遅くなりすみません。
    はい!自分も試しはしたのですがbefore_actionを消したらエラーは出なくなるのですが解決にはならなかったです(汗)
    step1ではUserモデル関係のみで住所(Addressモデル関係)は入力していないです。
    build_modelの使い方について調べ不足ですね、、、もっと調べてみます。
    ありがとうございました。

    キャンセル

  • 2019/10/09 16:28

    address_paramsを作ってみたのですが同じエラーでuserがemptyみたいです(汗)
    やはりviewの細かい部分でミスがあるのですかね、、、

    キャンセル

  • 2019/10/10 09:03

    param is missing or the value is empty: userの、ままなんですか?
    before_action :user_params は消したんですよね?

    キャンセル

  • 2019/10/10 15:55

    お返事ありがとうございます。
    やはりview側の問題でした(汗)
    = fields_forの最初にf.とつけていなかったせいでuserにネストされずにいたのが原因だったようです。
    たくさんのアドバイスと回答本当にありがとうございました!!

    キャンセル

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

  • ただいまの回答率 88.60%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る