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"