Ruby
Rails
Gem
Validation

細かい条件を元に判定結果を返す簡易 Validation 的な Judgment Gem を作ってみた

作ったもの

とりあえず、名前は仮で judgment として、github に置いてあります。

できる事としては下記のような感じ。

class SampleModel
  include Judgment

  judge_for :publishable do
    judge -> { saved? }, '保存されていません'
    judge -> { using? }, '利用者がいません'
    judge -> { reservation_date.future? }, '予約投稿日が未来です'
    judge_not -> { deleted? }, 'すでに削除されています'
  end
end

sample_model = SampleModel.new
sample_model.publishable? #=> false
sample_model.judgment_message(:publishable) #=> ['予約投稿日が未来です']

作ったきっかけ

Rails で、あるオブジェクトが色々な条件に一致するかどうかを調べるメソッドを作っていたら1つのメソッドがやたら長くなってしまい辛い場所が多数あった。

def publishable?
  !deleted? &&
    saved? &&
    using? &&
    !reservation_date.future? &&
    ...
end

また、条件に一致しなかった場合に、どうして一致しなかったのかが知りたい時があり、その場合はさらにメソッドを追加して

def why_not_publishable
  result = []
  result << '削除済み' if !deleted?
  result << '保存されてません' if saved? &&
  result << '利用者がいません' if using? &&
  result << '予約投稿日が未来です' if !reservation_date.future? &&
  ...
end

みたいな感じにする必要があって、publishable? を変更した時、why_not_publishable のメンテナンスを忘れるとさらに辛い。

何かいいものはないかと探してみたけど、考えてみると簡単に実装できそうだったので、とりあえず作ってみることにしました。

ToDo

  • 正直ネーミングセンスはどうかと思っているので、なんかいいのがあったら変えたい。
  • DSL もあれなので、メソッドを Symbol で受け取れるようにしたり、:if オプション入れたり、Validation っぽくしてもいいかも。