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

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

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

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

Q&A

解決済

1回答

1432閲覧

Ruby on RailsのRESTfulにルーターを設定した時のnewアクションについて

woohooman

総合スコア8

Ruby on Rails

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

0グッド

0クリップ

投稿2017/12/28 04:59

###Ruby on Railsのnewアクションについて

ruby on railsを使って、webアプリ(ツイッタークローン)を作っています。

RESTfulにルーターを設定した際に、
controllerに

Ruby

1def new 2 @user = User.new 3end

と作成し、ユーザー登録用ページ(users_new_path)を作成しています。

疑問なのは、
ユーザー登録用ページそのものは、GET(読み込み)のページであって、
コントローラーで他に定義しているcreateアクションでも

ruby

1def create 2 @user = User.new 3 4 if @user.save 5 flash[:success]="成功" 6 else 7 flash.now[:danger]="失敗" 8 end 9end

のように、newアクションを行なっています。

createアクションでnewアクションが重複になるのにも関わらず、
なぜ、ユーザー登録用ページで、newアクションを行なっているのでしょうか?

拙い質問ではありますが、誰かご回答いただけると幸いです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

あとで述べますが,create メソッド内の

rb

1 @user = User.new

は間違いでしょう。

さて,new アクションと new メソッドを混同されているのではないかと思いますので,ちょっと解説します。

UsersContollernew アクションは,新規入力画面を表示するためのアクションですよね。
で,このアクションはこのコントローラーの new メソッドで定義されています。
(アクションとメソッドは別物ですが,対応はしています)

しかし,この new メソッドの中にある User.newnew はアクションとは何の関係もありません。
空の User オブジェクトを作るためのものです。
なぜ空の User オブジェクトが必要なのでしょうか? それはビューで使うからです。

new アクションのビューとしては,自動的に,同名の new というテンプレートが使われますよね。
で,そのテンプレート中で,おそらく form という部分テンプレートを呼び出しているはずです。(ファイル名は _form.html.erb か何か)

その部分テンプレートに form_for(@user) みたいな記述がありませんか。
この @user は,UsersControllernew メソッドで代入されたもの,つまり,空の User オブジェクトです。
詳細は省きますが,フォームを作るためのヘルパーメソッド(form_for)で,モデルオブジェクトが必要なのです。

さて,実験として,コントローラーの new メソッドを

rb

1def new 2 @user = User.new 3 @user.name = "hoge" 4end

としてみましょう(name というカラムがあると仮定します)。

すると新規入力画面で名前のところに,デフォルトぽく「hoge」って入ってますよね。
フォームのヘルパーメソッドにモデルオブジェクトを渡すと,モデルオブジェクトのカラムの値が使われるんです。

new アクションが分かったところで,こんどは create アクションに行きましょう。
このアクションは,フォームの値をもとに User オブジェクトを作り,それをデータベースに保存するのが役割です。

なので,ここで

rb

1 @user = User.new

とするのは変です。
空の User オブジェクトを作るのではなく,フォームから送られたパラメーターに基づいた User オブジェクトを作らなければならないからです。

参考にされたものにどう書かれていたかわかりませんが,まあ例えば

rb

1def create 2 @user = User.new(user_params) 3 if @user.save 4 redirect_to @user, notice: 'ユーザーが追加されました。' 5 else 6 render :new 7 end 8end

みたいな感じでしょうか。
この user_params というのはプライベートメソッドとして,コントローラー内で例えば

rb

1private 2 3def user_params 4 params.require(:user).permit(:name, :email, 云々) 5end

みたいな感じに定義します。
ここの説明は,本題からそれるので省きますが,アクションとビューの関係を理解するため,もう少し続けます。

create メソッドでは,保存に成功したら @user にリダイレクトします。
詳細は省きますが,このように書くと,UsersControllershow アクションにリダイレクトするのです。
create アクションが成功したあと,show という別のアクションにリダイレクトされるわけです。

一方,保存に失敗した場合,リダイレクトはしないのですが,ビューのテンプレートとしては new が使われます。
new アクションのビューと同じテンプレートを使うのです。だって入力を訂正させたいんですからね。
このとき,フォームのヘルパーメソッドに,さっき作って保存しそこなった @user が渡ります。
これには各カラムに値が入っていますから,訂正用の入力画面ではそれらの値が表示されているはずです。

投稿2017/12/28 09:10

scivola

総合スコア2108

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

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

woohooman

2017/12/28 13:26

メソッドやアクションの違いがごちゃごちゃになって、理解が全く体系的にできていないことにとても気づかされました。 それぞれのコードの意味を理解できました!わかりにくい聞き方だったのにも関わらず、丁寧に解説いただき、ありがとうございました!
nekoyama7

2017/12/29 06:25

横レス失礼します。アクションとメソッドが同じ名前(機能は違う)なのは、混同しますね。私もそうでした。参考にしていた本に、ずいぶんと書き込みをしました。個人的には、scafforldを使わない場合でも、scaffordの生成する、コード、ルーティングに合わせることで、皆さんの共通認識が得やすいのでは? と思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問