動かざることバグの如し

近づきたいよ 君の理想に

Rails独自の型をActiveModel::Type::Valueを継承して作成する

環境

やりたいこと

RailsActiveModel::Attributesは本当に便利で ActiveRecordでもDBに紐づかないモデルのActiveModelでも重宝している

ActiveModel::Attributes が最高すぎるんだよな。 #Rails - Qiita

ただ標準で用意されている型の種類が少なく、オリジナルの型を作りたいと思った。

class Post
  include ActiveModel::Model
  include ActiveModel::Attributes
  attribute :category
end

やり方

ActiveModel::Type::Valueを継承したクラスを作成する

config/initializers/my_attribute.rbを作成して以下

例えばカンマ区切りの文字列の場合は自動で区切って配列化してくれる型を作りたいとする

class ArrayOrSingle < ActiveModel::Type::Value
  def cast_value(value)
    if value.is_a?(String) && value.include?(",")
      value.split(",")
    else
      value
    end
  end
end

ActiveModel::Type.register(:array_or_single, ArrayOrSingle)

あとは array_or_single を指定するだけ

class Post
  include ActiveModel::Model
  include ActiveModel::Attributes

  attribute :category, :array_or_single
end

確認

irb(main):003> Post.new(category: "diary").category
=> "diary"
irb(main):014> Post.new(category: "diary,cat").category
=> ["diary", "cat"]

参考リンク