質問: User.new if @user.save flash[:success]="成功" else flash.now[:danger]="失敗" end end ``` のように、newアクションを行なっています。 createアクションでnewアクションが重複になるのにも関わらず、 なぜ、ユーザー登録用ページで、newアクションを行なっているのでしょうか? 拙い質問ではありますが、誰かご回答いただけると幸いです。
回答: あとで述べますが,`create` メソッド内の ``` @user = User.new ``` は間違いでしょう。 さて,`new` アクションと `new` メソッドを混同されているのではないかと思いますので,ちょっと解説します。 `UsersContoller` の `new` アクションは,新規入力画面を表示するためのアクションですよね。 で,このアクションはこのコントローラーの `new` メソッドで定義されています。 (アクションとメソッドは別物ですが,対応はしています) しかし,この `new` メソッドの中にある `User.new` の `new` はアクションとは何の関係もありません。 空の `User` オブジェクトを作るためのものです。 なぜ空の `User` オブジェクトが必要なのでしょうか? それはビューで使うからです。 `new` アクションのビューとしては,自動的に,同名の `new` というテンプレートが使われますよね。 で,そのテンプレート中で,おそらく `form` という部分テンプレートを呼び出しているはずです。(ファイル名は `_form.html.erb` か何か) その部分テンプレートに `form_for(@user)` みたいな記述がありませんか。 この `@user` は,`UsersController` の `new` メソッドで代入されたもの,つまり,空の `User` オブジェクトです。 詳細は省きますが,フォームを作るためのヘルパーメソッド(`form_for`)で,モデルオブジェクトが必要なのです。 さて,実験として,コントローラーの `new` メソッドを ``` def new @user = User.new @user.name = "hoge" end ``` としてみましょう(`name` というカラムがあると仮定します)。 すると新規入力画面で名前のところに,デフォルトぽく「`hoge`」って入ってますよね。 フォームのヘルパーメソッドにモデルオブジェクトを渡すと,モデルオブジェクトのカラムの値が使われるんです。 `new` アクションが分かったところで,こんどは `create` アクションに行きましょう。 このアクションは,フォームの値をもとに `User` オブジェクトを作り,それをデータベースに保存するのが役割です。 なので,ここで ``` @user = User.new ``` とするのは変です。 空の `User` オブジェクトを作るのではなく,フォームから送られたパラメーターに基づいた `User` オブジェクトを作らなければならないからです。 参考にされたものにどう書かれていたかわかりませんが,まあ例えば ``` def create @user = User.new(user_params) if @user.save redirect_to @user, notice: 'ユーザーが追加されました。' else render :new end end ``` みたいな感じでしょうか。 この `user_params` というのはプライベートメソッドとして,コントローラー内で例えば ``` private def user_params params.require(:user).permit(:name, :email, 云々) end ``` みたいな感じに定義します。 ここの説明は,本題からそれるので省きますが,アクションとビューの関係を理解するため,もう少し続けます。 `create` メソッドでは,保存に成功したら `@user` にリダイレクトします。 詳細は省きますが,このように書くと,`UsersController` の `show` アクションにリダイレクトするのです。 `create` アクションが成功したあと,`show` という別のアクションにリダイレクトされるわけです。 一方,保存に失敗した場合,リダイレクトはしないのですが,ビューのテンプレートとしては `new` が使われます。 `new` アクションのビューと同じテンプレートを使うのです。だって入力を訂正させたいんですからね。 このとき,フォームのヘルパーメソッドに,さっき作って保存しそこなった `@user` が渡ります。 これには各カラムに値が入っていますから,訂正用の入力画面ではそれらの値が表示されているはずです。