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

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

ただいまの
回答率

91.24%

  • Ruby on Rails

    5380questions

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

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

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 45

woohooman

score 2

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

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

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

def new
 @user = User.new
end


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

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

def create
 @user = User.new

 if @user.save
  flash[:success]="成功"
 else
  flash.now[:danger]="失敗"
 end
end

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

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

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

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+3

あとで述べますが,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 が渡ります。
これには各カラムに値が入っていますから,訂正用の入力画面ではそれらの値が表示されているはずです。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/12/28 22:26

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

    キャンセル

  • 2017/12/29 15:25

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

    キャンセル

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

ただいまの回答率

91.24%

関連した質問

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

  • Ruby on Rails

    5380questions

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