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

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

ただいまの
回答率

88.81%

form_forがどのようにしてcontrollerを選択しているのか分からない

解決済

回答 2

投稿

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

taishiaaaaa

score 30

RailsTutorialさんより下の画像に載っているコードの仕組みが分かりません。
_follow.html.erbのform_forはどのようにしてRelationshipsコントローラーにPOSTリクエストを送ればよいと判断しているのですか?
「コントローラーの指定がない場合、扱っているデータのモデル名の複数形のコントローラーに送る」のような暗黙の了解が裏にあるのでしょうか?
なぜform_forはPOSTリクエストを送るべき場所がRelationshipsコントローラーのcreateアクションだと判別できるのか教えてください。
回答お待ちしております。
railstutorial
tutorial

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

0

form_forは引数にレコードを渡すと、そのレコードが新規作成のものか、既存のレコードかによって転送先を自動で推測してくれます。
例えば以下のようなコードは

<%= form_for(Post.new) do |f| %>
  ...
<% end %>

以下のコードと一緒の意味を持ちます。

<%= form_for @post,
             as: :post,
             url: posts_path,
             html: { class: "new_post", id: "new_post" } do |f| %>
  ...
<% end %>


対応するRESTfulなルーティングの設定をしている(つまりroutes.rbでresources :postsと定義している)場合は、上記のコードで postメソッドで/postsにルーティングしてくれる、つまりposts_controller.rbのcreateアクションが実行されることになります。

Railsチュートリアルの場合、/users/_follow.html.erbで、form_forの引数に新規作成したレコードを渡しているように見受けられますので、
createアクションが実行されるようにルーティングしてくれるのだと思います。

参考リンク

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/11/24 21:16 編集

    やはりPostモデルとpostsコントローラーの関連性がわからないです。Post.newという情報からurl: posts_pathが出てくるのは、やはり名称から判断しているのですか?

    キャンセル

  • 2018/11/24 22:17

    そうですね…その辺りを掴むには幾つか周辺知識が必要になると思います。

    まずRailsは設定より規約(CoC)という思想を掲げています。
    Railsが予め決めたルールに則ってコードを書くことで、開発者が逐一さまざまな設定をしたりコードを書いたりしなくて済みますよ、という考え方です。
    命名規則とかもそうで、Railsの慣習に従うことで色々な恩恵が受けられます。

    次にRESTという設計様式があります。
    HTTPメソッドとURLを組み合わせることで、あるデータモデルのデータ取得・作成・更新・削除(CRUD)を出来るようにする、というものだと思います。
    CRUD操作は殆どすべてのアプリケーションで必要とされる機能だと思います。
    そのため、インターネットを経由して利用されるWebアプリケーションでは、
    URLとHTTPメソッドを使ってアプリケーションのCRUD操作を呼び出すという
    RESTに則ったルート設計(RESTful なインターフェース)にすることはとても大切なことだと思います。

    RailsではRESTfulなルート設計を簡単に出来るようにするために、resourcesメソッドというものが用意されています。
    使い方も簡単で、config/routes.rbで
    resources :name
    と書きます。
    :nameの箇所にはCRUD操作したいテーブル名を指定します。例えばUserモデルを元に構成されたデータ群であれば:usersを指定します。
    (Userモデルに対応して生成されたデータベースのテーブル名がusersとなるのはRailsの命名規則です)

    resourcesメソッドを使うと、RESTfulなルーティングを一括で作成してくれます。
    合計で7つのルーティングが自動生成され、:nameと同じ名前のコントローラへと対応付けてくれます。
    参考:https://railsguides.jp/routing.html#crud%E3%80%81%E5%8B%95%E8%A9%9E%E3%80%81%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3

    例えば
    resources :users
    と設定した場合、/users というURLにPOSTメソッドでアクセスすると、usersコントローラのcreateアクションにルーティングされます(この辺りもRailsの命名規則による仕様です)。
    そしてusersコントローラのcreateアクションでは、Userモデルのデータを作成するメソッドが実行されることが期待される、というわけです。

    Railsではリソースベースのルーティングが推奨されます。
    form_forのように自動で転送先を推測してくれる系のメソッドも、
    こうした規約を踏襲していると思います。
    そのため
    <%= form_for(Post.new) do |f| %>
    のように引数に新規作成されたモデルのインスタンスが渡されると、
    createアクション(データの作成用のメソッド)に向けてルーティングしてくれるのだと思います。

    キャンセル

  • 2018/11/24 22:18

    モデルとコントローラの関係も、Railsの規約に基づいて考えていくと理解しやすいと思います。
    (長文失礼しました;)

    キャンセル

  • 2018/11/24 23:27

    「:nameの箇所にはCRUD操作したいテーブル名を指定します」
    あれは単に名前を決定していたのではなくテーブル名を指していたのですね!何度も読んで理解していたつもりだったresourcesの意味が改めて理解できました。Userモデルとは違うテーブルの操作をusersコントローラーで動作させようと考えていてつまづいていたところでした。丁寧な回答ありがとうございました、また分からなくなったら見返したいと思います。

    キャンセル

0

form_forの内部では、モデルから必要なURLを読み取っています。具体的には、polymorphic_pathというヘルパーを使って、モデルのクラスからそれに対応するURLを生成しています(ソース)。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/11/24 23:23

    回答ありがとうございます。もっと体系的な知識をつけたタイミングでもう一度読んで理解に努めたいと思います。

    キャンセル

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

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

関連した質問

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