1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Railsのform_withを自分なりにまとめてみた

Last updated at Posted at 2023-08-02

はじめに

未経験からプログラミング学習中のkekiと申します。

Railsのログインの仕組みを理解する中で、form_with の機能と個人的に難しかった疑問二点を記事にしてみました。
ログイン付近を学習中の方や、その復習をしたい方向けの内容です。
修正・追記あれば随時更新していきます。

form_withとは

Railsで情報を送信するためのヘルパーメソッドです。
form_withを使うことにより、簡単に入力フォームに必要なHTMLを作成することができます。
かつてのform_tagform_forメソッドをひとまとめにした大変便利なものです。
以下のような初期設定があります。

  • HTTPメソッドのPOSTPATCHを自動的に切り替えてくれる
  • デフォルトではid属性やclass属性は付与されない
  • デフォルトでremote: trueが付与
  • 関連モデルがある場合はモデルを指定し、ない場合はURLを指定する

主な機能

大きく6つにまとめました。

  1. 自動的に送信先のアクションをcreateかupdateに振り分けてくれる
    おそらく最も恩恵を受けている機能です(参考記事はこちら)。
    HTTPメソッドを個別に指定することもできます。

  2. スコープを指定することができる
    例えばusersコントローラとは別にsessionsコントローラを作り、ログイン画面でユーザーの情報を取得する際は以下のようなスコープの設定になります。
    (詳細は下述します)

    <%= form_with scope: :session, url: sessions_path do |f| %>
      <%= f.text_field :name %>
      <%= f.submit %>
    <% end %>
    

  3. form_withにはモデル属性にない入力フォームを追加できる

    <%= form_with model: @user, url: users_path do |f| %>
      <%= f.text_field :name %>
      <%= f.text_field :hoge%>
      <%= f.submit %>
    <% end %>
    

  4. デフォルトでremote: true設定(Ajaxでのリクエストがオン)になっている
    →リモート無効のフォームにしたい時はlocal: true に変更する
    (詳細は下述します)

  5. form_withにはHTMLのclassやidを設定することができる(あまり使わないかも)

    <%= form_with model: @user, id: :任意のID, class: :任意のclass do |form| %>
      <%# フォームの部品 %>
    <% end %>
    

  6. その他formタグで様々なオプションをつけることができる

    • form.htmlでhtmlタグをつけると投稿の種類が変わる
    • form.hidden_fieldは非表示のフォームを作成し、ユーザーのidなどユーザーがフォームから入力しない情報をパラメータとして渡したいときに使える
    • form.submitは送信ボタンを作成する

自分の疑問点

<%= form_with(scope: :session, url: sessions_path, local: true) do |f| %>
  • local: trueって何してるの?

    これはAjax(エージャックス)処理のオフを指しています。

    Ajaxとは「JavaScriptでサーバー側との通信を非同期で行い、通信結果によって動的にページの一部だけ書き換える手法のこと」です。form_withはデフォルトでAjax処理が行われる設定なので、これを無効にする際にはlocal: trueが必要になります)

    local: trueを使ってる理由に関しては、以下の記事が詳しいのでぜひ参考にしてみてください!
    form_withのlocal: trueって必要なん?これ何なん?(Ruby on Rails)


  • scope: :リソースの名前(ここではsession)って何してるの?

    sessionsコントローラに相当するモデルが存在しないので、それに対応する受け皿となるフォームのオブジェクトを設定するために使用しています。

    例を挙げます。
    createアクションでユーザーのemailのパラメーターを取得するために、user = User.find_by(email: params[:session][:email].downcase) のように指示されているとします。その時のリクエストを見てみると、次のようになります。

    Processing by SessionsController#create as HTML
      Parameters: {"utf8"=>"✓","authenticity_token"=>"fboHRR7XfTbsN7SxgjLgLx3uWDzzj7HC1hi8H/q3zX7mQpHU. 2B8HwgVBXYqyLEaSt4rwxNWJGHeoworyY8MoLw==",
       "session"=>{"email"=>"メールアドレス", "password"=>"[FILTERED]"}, "commit"=>"Log in"}
    

    ※この時のform_withでの送信データはデータベースに保存されるわけではなく、cookieとしてブラウザに保存されています

    コードの最後の行を見てみると、 “session”というキーの中に、更に"email"=>"メールアドレス", "password"=>"[FILTERED]"という別のハッシュが含まれているのが分かります。つまりハッシュの入れ子構造になっています。
    params[:session][:email]のように2つシンボルが続いているのは、入れ子になっている内部の方のキーを指しています。:sessionをform_with内でスコープ指定することで、このような入れ子のハッシュのデータをデータベース無しで引き出すことができます

    このようにscopeを加えると、生成されるhtmlの属性の構造が変わり、そのおかげでモデルが無くてもグループ化してデータを引き渡すことが可能です。

おわりに

form_withのまとめでした。
まとめるにあたって、Ajax関連のJavaScriptの理解やログイン情報のデータの流れが少しわかってきたので、よい学習になりました。同じような未経験の学習者の方々の助けになれば幸いです。

他にも様々な機能やオプションがありますので、気になった方はぜひご自身でも調べてみてくださいね。

参考サイト

Rails 5.1〜7.0: ‘form_with’ APIドキュメント(翻訳)
Rails:form_withのオプションや特徴について整理
Ajaxとは?初心者向けに豊富な画像で仕組みを解説
form_withの:scopeオプション - プログラミング学習ノート

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?