実践で学ぶRuby on rails 〜仮説千本ノック〜

プログラマーとして独立するため日々スキルアップに励んでいます。優れたプログラマは仮説を立てるのがうまい。そこを目指して仮説を立てては検証する日々です!!

form_forの使い方

現在プログラミングスクールのカリキュラムで、チャットアプリの実装を行なっています。

 

チャットはテーマ別に行われるため、

グループを、「サッカー」「バスケ」等、テーマ別に作るためのグループ作成フォームを作成します。

フォームに、グループ名、所属させるメンバーを入力し、送信すると新規グループが登録されるわけです。

 

では、そのためのフォームをどうやって作ればいいのか??

 

form_forというヘルパーメソッドを使えば簡単に作れるようです。

以前、フォームにはinputタグを使った書き方を学びましたが、これはセキュリティ上の配慮に欠けており、おすすめできません。

form_forで書くと、自動的にセキュリティを配慮したコードもくっついてくるので楽チンです。

 

以下、各ファイルに何を記述すれば良いのか説明します。

 

■ビュー

new.html.haml(新しいグループを作るためのページなのでnew)

= form_for  @group do |f|

先頭にこれを書き、続けて、グループ名、所属させるユーザー等を入力するフォームを1つずつ記述。

 

form_forの引数として「@group」を使っていますが、

これは、フォームによって新規に作成したいインスタンス

つまり、このフォームは新しいgroupインスタンスを作るためのものですから、@groupとなります。

 

なお、チャットアプリでメッセージを作成するフォームでは、

単に@messageとすれば良さそうですが、

メッセージは「あるグループに属する」ことが前提となりますので、その情報も加えて、次の通りとなります。

= form_for  |@group, @message| do |f|

 

ちなみに、グループ名、所属させるユーザー等を下に続けて記述していくに当たっては、この形式で書きます。

 

= form_for  @group do |f|

 = f.タグ名 :送信した値を保存するカラム

 

タグは、フォームに入力する内容が、長い文字列なのか、短いのか、数字を入れるのか、アドレスを入れるのかで決まってきます。

例えば、

= form_for  @group@ do |f|

 = f.text_field :name

とすれば、

ここに入力したものは、groupsテーブルのnameカラムに保存されます。

 

■各フォームの書き方

①= f.label

通常、2つ1組で使われ、後にかく入力エリアを選択しやすく(クリックっする面積を増やす)してくれる

= f.label :(データ保存先のカラム), class: "〇〇〇〇__label"

= f.text_field :(同じ),class: "〇〇〇__text"

 

ex

= f.label :name, class: "form__label"

= f.text_field :name,class: "form__text"

 

ただし、画像送信フォームに、ファイル選択機能を追加する時は、

= f.labelの下にアイコンやファイル選択機能を配置するため、doをつけて、下の要素はインデントする。

なお、= f.labelの親要素として書く=form_forにもdoはある。

 

= form_for |@group, @message| do |f|

 = f.label :(データ保存先のカラム), class: "〇〇〇〇__label" do

  = icon("far", "fontawsomeで指定されたワード")

  = f.file_field :(データ保存先のカラム),class: "〇〇〇__file"

 

 

②= f.submit

form_forがなかった時代は、name、disable-with等のたくさんのプロパティを記述していたが、form_forの子要素としてかくならば、

シンプルに書けば、あとは自動的に決めてくれる。

= f.submit "ボタンに表示されるテキスト", class: "〇〇〇〇__btn"

ex 

= f.sbmit "Send", class: "form__submit"

 

 

 

■各入力項目にクラス名をつけたり、サイズを変更したりしたい

カラム名に続けて記述することで、クラス名、サイズの指定を行うことも可能です。

 

= form_for  @group do |f|

 = f.text_field :name, class: "〇〇", size: 〇〇

 

 

チェックボックスを利用したフォーム

なお、フォームには、テキストを入力するほか、チェックボックスタイプの入力も可能です。

自分で、1つずつ、チェックボックスに表示するテキストを手打ちするパターン。

= form_for  @group@ do |f|

 = f.check_box :sex(男or女の二択)

 

手打ちせず、すでに作ったテーブルの値を表示させることも可能です

= form_for  @group@ do |f|

 = f.text_field :name

 = f.collection_check_boxs ①:user_ids, ②User.all, ③:id, ④:name=

collectio

collection_check_boxsタグを使用するとき、引数がたくさんなので、整理します。

①まず、チェックボックスで入力したデータ(新規作成したグループにどのユーザーを所属させるか)を、「中間テーブル」のどのカラムに「保存」するかを指定し、

そのカラムに保存する値を③で指定。

user_idsカラムに保存する値だから、当然idとなります。

 

チェックボックスにusersテーブルのnameを表示させるために、

まずは、全てのユーザーデータを取得し、続いて④で指定したカラムの情報を表示させる。

 

①と③、②と④が関連しているのですが、なぜだか、このように混じり合った順番で引数を指定するようになっています。

 

 

なお、前提として、

テーブルは3種類あり、サッカーグループを作成し、フォームを送信した結果、下記の状態を作り出したいものとします。

●groupsテーブル

|id|name      |

|1 |サッカー|

 

●usersテーブル

|id|name       |

|1 |Douan     |

|2 |Minamino|

 

●group_usersテーブル

サッカーグループには、DouanとMinaminoの二人が参加していることを示す中間テーブル

|id|group_id |user_id |

|1 |1             |1           |

|1 |1             |2           |

  

■コントローラー

group_controller.rb

もちろん、ビューであるnew.html.hamlで@groupを使うためには、その前段階として、対応関係にあるgroupコントローラーのnewメソッドで、@groupを定義する必要があります。

 

def new

 @group = Group.new

end

 

■フォームで入力した内容の送信先

では、入力した内容を送信すると、一体どこに送信されるのか。コードを見ても、パスもHTTPメソッドも書いてないので分かりませんが、そこは、railsのいいところ。

 

コントローラーで、Group.new作成したインスタンスは新規であり、何も送信先に関する情報を持っていないため、そのことだけを判断材料に、自動的にcreateアクションへと引き継がれ、結果、createアクション自体が持っている送信先へと送られ、保存されます。

 

なお、一度作成したグループ情報を編集するケースでは、全く同じフォームを活用しますが、インスタンスが新規ではなく、保存ずみのレコードから持って来るため、区別され、createではなく、updateアクションへと引き継がれ、updateアクションがもつ送信先へと送られます。

 

■form_forにクラス、IDをつけたい

次のように、インスタンスに続けてhtml:~~を記述すればつけられます。

form_for @group, html: {class: "〇〇"} do |f|