ActiveModel::Attributesでカスタムタイプを使う
Rails 5.2.0 で入ったActiveModel::Attributes API 最高ですよね。
でもカスタムタイプのドキュメントが見つからないんですよね。 ActiveRecord::Attributes API のカスタムタイプ ならあるのですが。
ソースコード見たところ簡単に作れるのがわかったので紹介します。
まず型の登録部分ですが、lib/active_model/type.rb で定義されています。
また、ActiveModelで使われているデフォルトタイプの実装を見ると cast_value
メソッドがあればよさそうです。
ActiveRecord::Attributes API と同様に実装します。
class MoneyType < ActiveModel::Type::Integer def cast_value(value) if !value.kind_of?(Numeric) && value.include?('$') price_in_dollars = value.gsub(/\$/, '').to_f super(price_in_dollars * 100) else super end end end # config/initializers/types.rb ActiveModel::Type.register(:money, MoneyType) # app/models/store_listing.rb class StoreListing include ActiveModel::Model include ActiveModel::Attributes attribute :price_in_cents, :money end store_listing = StoreListing.new(price_in_cents: '$10.00') store_listing.price_in_cents # => 1000
このように ActiveModel::Attributes でカスタムタイプを使うことができます。