5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

カラム型TINYINTの場合にActiveRecord::Enumを使いたい

Last updated at Posted at 2016-10-25

ハマったのでメモ。
まあRailsで1から作っている場合は遭遇しないかもしれませんが・・・。

ActiveRecord::Enumとは

割愛。
http://ruby-rails.hatenadiary.com/entry/20150710/1436461745

問題

class User < ApplicationRecord
  enum state: { pending: 0, active: 1 }
end


user = User.new(state: :pending)
# => #<User:0x007fbdbf882a78 id: nil, state: 'pending'>
user.save!
# => true
user
# => #<User:0x007fbdbf882a78 id: 1, state: nil>

例外も発生せず、データベースを直接覗いてもデータはきちんと入っているのに、save!するとstatenilになった!?!?

原因

stateカラムがTINYINTだった。ActiveRecordは、カラムがTINYINT(1)の場合、自動的にbooleanとみなしてキャストするらしい。今回の場合(enumの場合)、enumのvalueにしていたのが数値だったために「(キャストした値)true/falseに該当するlabelがない」=> nilとなっていた様子。

解決策

class User < ApplicationRecord
  attribute :state, ActiveRecord::Type::Integer.new
  enum state: { pending: 0, active: 1 }
end

これでActiveRecordがstateカラムを整数値としてキャストしてくれるようになる。
参考(https://blog.kazu69.net/2015/10/22/active-record-tinyint/)
(ちなみにリンク先で「TINYINT(1)はbooleanと同じなので0 か 1 しかとらない」とありますが、TINYINT(1)は場合-128~127 の値をとれます。booleanも同様)

5
0
0

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
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?