環境
Rails 5.0.6
ruby 2.5.1
はじめに
railsにはtinyintをbooleanとして認識することができる便利な機能があります。
しかし、昔から運用しているアプリケーションでは、容易にtrueにはできない状況が発生します。
# たとえば以下のコードは、tinyint_columnがbooleanになってしまうと条件がコケる
if tinyint_column == 1
...
end
そのため、泣く泣くこのオプションをOFFにしていました
config/application.rb
ActiveRecord::ConnectionAdapters::Mysql2Adapter.emulate_booleans = false
しかし、booleanで扱えるといろいろ便利な場面が多いのも事実です。
新規で作成するモデルや、利用するgemのモデルではぜひとも利用したい!!
ということで、やってみました
対処法
今回は、moduleを作り、対象モデルでincludeすることで実現します。
app/lib/emulate_boolean_type.rb
module EmulateBooleanType
extend ActiveSupport::Concern
included do
emulate_boolean_type!
end
class_methods do
def emulate_boolean_type!
return unless ActiveRecord::Base.connection.data_source_exists? table_name
tinyint_columns = columns_hash.select{|_name, col| col.sql_type == 'tinyint(1)'}.keys.map(&:to_sym)
tinyint_columns.each do |col|
attribute col, ActiveModel::Type::Boolean.new
end
end
end
end
app/models/hoge.rb
class Hoge
include(EmulateBooleanType)
...
end
以上です。
めでたしめでたし