ActiveRecordのカラムのように、"0" を false に変換したり、"2020/02/26 12:30" をTimeオブジェクトに変換したりする方法です。フォームから受け取った値をActiveRecord以外のクラスで処理するときに使えます。
環境: Rails 5.1, 5.2, 6.0
型キャストを使うには、ActiveModel::Type::Valueのサブクラスをnewしてcastメソッドを呼び出します。true/falseにしたければ、ActiveModel::Type::Boolean です。[false, 0, "0", "f", "F", "false", "FALSE", "off", "OFF"]
はfalse、それ以外はtrueになります。
ただし、nil と "" は nil になります。また、Rails 5.2.4 と 6.0.0 以降では、[:"0", :f, :F, :false, :FALSE, :off, :OFF]
も falseになるよう修正が入っています。
attr_reader :draft
def draft=(val)
@draft = ActiveModel::Type::Boolean.new.cast(val)
end
日付型(Dateクラス)や日付時刻型(Timeクラス)にしたいときは、ActiveModel::Type::Date、ActiveModel::Type::DateTime を使います。
Date.parse(val)
や Time.parse(val)
とすると書式が不正なときに例外が発生しますが、Railsの型キャストではnilになります。
attr_reader :published_at
def published_at=(val)
@published_at = ActiveModel::Type::Date.new.cast(val)
end
ほかにどんな型が使えるのかは、Railsのソースの activemodel/lib/active_model/type 下を参照してください。