はじめに。
本記事はform_forとform_tagの使い分けについて書いたものになります。
form_forとform_tagをそれぞれどのような時に使えば良いのかを書きたいと思います。間違っている点や良い点があればコメント欄にいただけますと嬉しいです。
本記事の環境
- Ruby 2.4.4
- Rails 4.2.9
- macOS Sierra
結論から
先に結論を書きたいと思います。結論としては以下のようになります。
- form_tag
- データベースのレコードを検索して表示したいとき
- form_for
- モデルオブシェクト(データベース)にデータを登録したいとき。
下準備
まずは記事を進めていくにあたって、下準備を行います。もうわかってるぜ!という方は読み飛ばしてください。
railsのアプリを作成します。次のコマンドでversionを4.2.9に指定しつつ、アドレス帳アプリを作成しています。
-d オプションでデータベースをMySQLを指定しています。
rails _4.2.9_ new address_book -d mysql
次にデータベースを作成して、マイグレーションします。
rake db:create
rake db:migrate
今回のアドレス帳アプリで利用するaddressモデルを作成します。
いつもモデル名を単数形表示にするか、複数形にするか迷いますがここは、アドレスを登録するためのテーブル(入れ物)をデータベースに1つ作成するから
単数形として覚えてます。(混乱するのは私だけかもしれません汗)
ちなみにモデル名の後にカラム名やカラムのタイプを指定することで一緒にカラムの作成が出来ますが、見づらくなったりタイポしやすくなるので
後から作成するようにしています。
rails g scaffold AddressBook
テーブルにカラムを追加します。今回はaddress_bookテーブルに追加するのはアドレス帳に登録したい人の名前(string:name), 登録したい人の電話番号(string:phone)、登録したい人の住所(string:address)です。scaffoldコマンドを実行した後に/db/migrateフォルダに作成されるマイグレーションファイルを編集します。(yyyyは年,mmは月,ddは日付,xxxxxxはマイグレーションファイルが作成された何時何分何秒になります。)
class CreateAddressBooks < ActiveRecord::Migration
def change
create_table :address_books do |t|
t.string :name
t.string :phone
t.string :address
t.timestamps null: false
end
end
end
データベースにテーブル(AddressBook)のへの変更をrake db:migrateコマンドを実行して反映させます。
rake db:migrat
これで下準備ができました!
どうやって使うのか? - form_for
form_forはデータベースにレコードを登録したいときに利用します。
今回は解説のためにあえてパーシャルは使わずに直に書きたいと思います。
まずはコントローラを編集します。編集する場所はストロングパラメータを編集します。scaffoldコマンドを使った際にカラムを指定していれば
ストロングパラメータ(address_book_paramsメソッド)に許可するフォームからの値を追加してくますが、指定していないのでpermitメソッドで追加しています。
なお、scaffoldコマンドを使うとコントローラやviewファイルを自動作成してくれます。個人的に基礎を覚えるならコントローラやモデル、viewなどは別々に作成したほうがよいのではと思いますが、今回は時間短縮のためにscaffoldコマンドを使っております。。。
基本的な構文はrailsの公式サイトを参照ください。
class AddressBooksController < ApplicationController
before_action :set_address_book, only: [:show, :edit, :update, :destroy]
# GET /address_books
# GET /address_books.json
def index
@address_books = AddressBook.all
end
# GET /address_books/1
# GET /address_books/1.json
def show
end
# GET /address_books/new
def new
@address_book = AddressBook.new
end
# GET /address_books/1/edit
def edit
end
# POST /address_books
# POST /address_books.json
def create
@address_book = AddressBook.new(address_book_params)
respond_to do |format|
if @address_book.save
format.html { redirect_to @address_book, notice: 'Address book was successfully created.' }
format.json { render :show, status: :created, location: @address_book }
else
format.html { render :new }
format.json { render json: @address_book.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_address_book
@address_book = AddressBook.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def address_book_params
params.fetch(:address_book, {}).permit(:name, :phone, :address) #この部分を編集
end
end
<h1>New Address Book</h1>
<%= form_for(@address_book) do |f| %>
<%= f.label :name, '名前'%>
<%= f.text_field :name ,placeholder: '名前を入力' %>
<%= f.label :phone, '電話番号' %>
<%= f.text_field :phone ,placeholder: '電話番号を入力' %>
<%= f.label :address, '住所' %>
<%= f.text_field :address, placeholder: '住所を入力' %>
<%= f.submit '登録'%>
<% end %>
<%= link_to 'Back', address_books_path %>
どうやって使うのか? - form_tag
form_tagはデータベースに登録されているレコードの検索結果などを表示させたいときに利用します。
まずはコンローラファイルを編集します。index.html.erbのフォームから受け取ったkeyword属性の値を@find_address_booksに格納して
whereメソッドで曖昧検索をさせます。
class AddressBooksController < ApplicationController
before_action :set_address_book, only: [:show, :edit, :update, :destroy]
# GET /address_books
# GET /address_books.json
def index
@find_address_books = AddressBook.where('name LIKE(?)', "%#{params[:keyword]}%") #この部分を編集
end
##省略しています。
private
# Use callbacks to share common setup or constraints between actions.
def set_address_book
@address_book = AddressBook.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def address_book_params
params.fetch(:address_book, {}).permit(:name, :phone, :address)
end
end
<p id="notice"><%= notice %></p>
<h1>Listing Address Books</h1>
<%= form_tag('/address_books', method: :get) do %>
<input name="keyword" type="text" placeholder="名前で検索します。" value="">
<button title="検索" type="submit">検索</button>
<% end %>
# ↑ form_tagメソッドでkeyword属性の値を/address_booksに飛ばしています。
<table>
<thead>
<tr>
<tr>名前</tr>
<tr>電話番号</tr>
<tr>住所</tr>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @find_address_books.each do |address_book| %>
<tr>
<td><%= address_book.name %></td>
<td><%= address_book.phone %></td>
<td><%= address_book.address %></td>
<td><%= link_to 'Show', address_book %></td>
<td><%= link_to 'Edit', edit_address_book_path(address_book) %></td>
<td><%= link_to 'Destroy', address_book, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<%= link_to 'New Address book', new_address_book_path %>
まとめ
アドベントカレンダー2018 の8日目でした。
Form_forとform_tagの使い分けという名目で書かせていただきました。
来年はもっと見ていただけるかたのためになる記事を書きたいと思います。
ここまで読んでくださったかたありがとうございました。