LoginSignup
4
2

More than 5 years have passed since last update.

# form_forとform_tagの使い分けについて。

Last updated at Posted at 2018-12-08

はじめに。

本記事は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はマイグレーションファイルが作成された何時何分何秒になります。)

address_book/db/migrate/yyyymmddxxxxxx_create_address_books.rb

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の公式サイトを参照ください。

address_book/app/controllers/address_books_controller.rb

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
address_book/app/view/new.html.erb

<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 %>

1.png

どうやって使うのか? - form_tag

form_tagはデータベースに登録されているレコードの検索結果などを表示させたいときに利用します。
まずはコンローラファイルを編集します。index.html.erbのフォームから受け取ったkeyword属性の値を@find_address_booksに格納して
whereメソッドで曖昧検索をさせます。

address_book/app/controllers/address_books_controller.rb

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
address_book/app/view/index.html.erb

<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 %>

2.png

3.png

まとめ

アドベントカレンダー2018 の8日目でした。
Form_forとform_tagの使い分けという名目で書かせていただきました。
来年はもっと見ていただけるかたのためになる記事を書きたいと思います。

ここまで読んでくださったかたありがとうございました。

4
2
1

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
4
2