箱のプログラミング日記。

えんじにあ奮闘記

Railsのbooleanの扱いをちょっと追ってみた【Rails】

f:id:y_hakoiri:20191102121704j:plain

Railsで真偽値(boolean型)を使うに当たって、パラメーターやDB間でどのように受け渡しされるのかというのをちょっと追ってみた。

migration

classCreateUsers < ActiveRecord::Migration[5.1]
  def change
    create_table :users do |t|
      t.string :name, null: false
      t.string :email, null: false, index: true
      t.boolean :mail_magazine
      t.timestamps
    end
  end
end

今回はユーザーモデルにメルマガを送って欲しい人かどうかという意味でmail_magazineカラムを作成。trueの場合はメルマガを送り、falseの場合は送らないという仕様。

new.html.slim(ユーザー新規作成画面)

= bootstrap_form_for @user do |f|
 = f.text_field :name
 = f.text_field :email
 = f.form_group :mail_magazine
  = f.check_box :mail_magazine
 = f.submit

チェックボックスにチェックが入っていたらvalueはtrueとなり、なかったらfalseが入る。

フォームが出来上がったので、今回は以下の内容で新しいユーザーを作成してみる

  • 名前:新しいユーザー
  • メールアドレス:sample@gmail.com
  • メルマガ:送る(true)
Parameters: {"utf8"=>"", "authenticity_token"=>"****", "user"=>{"name"=>"新しいユーザー", "email"=>"sample@gmail.com", "mail_magazine"=>"1"}, "commit"=>"送信"}

ログを見ると、チェックボックスをチェックしたmail_magazineのvalueが「"1"」になっていることが確認できる

データベース側でカラムの型を指定していても、フォームに入力する時点ではそれがなんの型なのかというのは検知できないため、パラメーターでは全てが文字列で渡される...ってのはそういえば今までも知ってたな。

DBに格納する前(save時)に文字列だったパラメーターをtinyintの「1」に変換してから格納するみたい。

そのあとにINSERTした部分を見てみると、ちゃんと「1」になっている。

SQL (25.8ms)  INSERT INTO `user` (`name`, `email`, `mail_magazine`, `created_at`) VALUES ('新しいユーザー', 'sample@gmail.com',  1, '2020-01-15 20:50:28')

DBの中を覗いてみると

mysql> SELECT * FROM users WHERE id = 1;
+----+--------------------------------------+-----------------+---------+
| id | name     | email          | mail_magazine |  created_at  |
+----+--------------------------------------+-----------------+---------+
| 1 | 新しいユーザー  | sample@gmail.com   | 1      | 2020-01-15 20:50:28 | 
+----+--------------------------------------+-----------------+---------+

ちゃんと1になってるー。って思ったけど、これじゃ型の違いが分かんなかったw

とりあえずパラメーターでは文字列で渡されてsave前に変身するところまで理解。

ちなみにオブジェクトに格納されると真偽値で取り出せるので、例えばビューとかコントローラーとかでデバッグしてみるとこんな感じだった。

[1] pry(#<#<Class:0x00007f95d9973f30>>)> @user.mail_magazine
=> true
[2] pry(#<#<Class:0x00007f95d9973f30>>)> @user.mail_magazine_before_type_cast
=> 0
[3] pry(#<#<Class:0x00007f95d9973f30>>)> @user.mail_magazine_before_type_cast.to_s
=> "0"

参考: Railsでのブール型(Boolean)の扱い - LukeSilvia’s diary