クリックしてテーブルにレコードを追加・削除(button_toメソッド)


はじめに

button_toの概要とlink_toとの違いについて書いていこうと思います。

参考記事
https://pikawaka.com/rails/button_to

ビューファイルはhamlを利用します。
hamlが分からない方は以下を参照ください。
https://pikawaka.com/rails/haml

ファイルの準備

今回はクリックするとテーブルにレコードを追加したり削除したりする機能を実装してみようと思います。
完成イメージは下のような感じです

では早速準備していきましょう!
まずはモデルとテーブルを作成していきます。

モデル

ターミナル
$ rails g model count
migrationファイル
class CreateCounts < ActiveRecord::Migration[5.2]
  def change
    create_table :counts do |t|
      t.integer :number, null: false
      t.timestamps
    end
  end
end

今回はnumberカラムを用意しておきました。(特に理由はありません)
マイグレーションファイルを追記したらmigrateしておきます。

ターミナル
$ rails db:migrate

続いてコントローラを作成してルーティングを設定しておきます。

コントローラ

ターミナル
$ rails g controller counts
counts_controller.rb
class CountsController < ApplicationController
  def create
    Count.create(number: 1)
    redirect_to root_path
  end

  def destroy
    Count.last.destroy
    redirect_to root_path
  end
end

ルーティング

routes.rb
Rails.application.routes.draw do
  # (略)
  resources :counts, only: [:create, :destroy]
end

これで準備できました。

button_toメソッド

button_toメソッドの書き方は下のような感じです。

button_to "ボタン名", { パス or コントローラー名とアクション名 }, { オプション }

第1引数にはボタンに表示されるテキストを、第2引数ではボタンをクリックした時に動くアクションを指定するコードを、第3引数にはオプションを指定します。オプションはメソッドを指定する時なんかに使います。
個人的に第2引数はパスを書いた方が使いやすいです。(一応両方書いてみます)

今回はボタンを押すとnumberカラムに1を追加するボタンと最新のレコードを削除するボタンを作ります。

ビューファイル
カウント
= Count.all.length

= button_to "カウントボタン1", {controller: "counts", action: "create"}
= button_to "カウントボタン2", counts_path

- if Count.exists?
  - id = Count.last.id
  = button_to "削除ボタン1", {controller: "counts", action: "destroy", id: id}, method: :delete
  = button_to "削除ボタン2", count_path(id), method: :delete

第2引数にはコントローラ指定ver.とパス指定ver.の両方を記述しておきました。
(どちらも同じ動きをします)
ブラウザで動作確認してみると下のようにちゃんと動いてくれてます。

button_toではデフォルトがpostメソッドなのでcreateアクションを動かす場合はメソッドの指定(第3引数)は不要になります。ですのでdestroyアクションを動かすためにはdeleteを指定する必要があります。

ちなみに第3引数にはメソッドの指定の他にもクラス名の指定とかもできます。
クラス名の指定はメソッド指定の後ろに続けて書くこともできます。(第4引数っぽくなりますね)
書いてみると下のような感じです。

ビューファイル
= button_to "カウントボタン", counts_path, class: "count-btn"
= button_to "削除ボタン", count_path(id), method: :delete, class: "delete-btn"

2つ目のちなみにですが、ビューファイル中の if 〜はcountのレコードが0になったときにエラーを回避するためです。(レコードがないと削除するidを指定できないので)

link_toとの違い

link_toメソッドでも同様のことができますが、大きく違いが2つあります
・button_toはフォームが作成され、link_toはリンクが作成される
・link_toはデフォルトでGETメソッドが動く

実際にコードを書いて確かめてみましょう!

ビューファイル
= button_to "button_to", counts_path
= link_to "link_to", counts_path, method: :post

どちらも同じく動作していますね!
さらに検証ツールを使えば違いがよくわかります。

link_toはaタグを生成するだけですが、button_toはformを作りその中にinputタグでボタンが生成されます。
見た目的にもbutton_toはボタンの形に、link_toはリンクの形になっていますね。

まとめ

以上、button_toメソッドの使い方とlink_toとの違いを解説してみました。
これといった使い分けは思いつきませんが、cssを当てる時にやりやすいように使い分けすれば良いのではないでしょうか。(テキトーですみません)

間違いがあれば教えていただけると助かりますm(_ _)m