Active Modelを使って、Classにバリデーションなどの便利機能を追加 [Rails 4.2]


RailsのModelで便利に使っているバリデーションなどの機能をオブジェクトに追加する際には、include ActiveModel::Model がお手軽で便利ですよというお話です。
ちょっとボケて失念してしまっていたので、念のためメモです。


😎 できること

この include ActiveModel::Model できることはこちら。

  • Hoge.new({fuga: pugi}) みたいなイニシャライズができる
  • attributeのバリデーションを作れる
  • form_for などで使える

🐹 実装例

オブジェクトの実装はこちら。

# app/forms/non_model.rb
class Form::NonModel
# ------------------------------------------------------------------
# Modules
# ------------------------------------------------------------------
include ActiveModel::Model # Modelの便利機能とか
# ------------------------------------------------------------------
# Attributes
# ------------------------------------------------------------------
attr_accessor :foo, :bar
# ------------------------------------------------------------------
# Validations
# ------------------------------------------------------------------
validates :foo, presence: true
validates :bar, presence: true
end

オブジェクトを使う際はこちら。

# バリデーションOKのオブジェクト
vaiid_form = Form::NonModel.new(foo: 'foooo', bar: 'baaaan!')
vaiid_form.valid? #=> true
# バリデーションNGのオブジェクト
invalid_form = Form::NonModel.new(foo: 'foooo')
invalid_form.valid? #=> false
invalid_form.errors #=> #<ActiveModel::Errors:0x007fe6bb19df58 @base=#<Form::NonModel:0x007fe6beec6038 @errors=#<ActiveModel::Errors:0x007fe6bb19df58 ...>, @foo="foooo", @validation_context=nil>, @messages={:bar=>["を入力してください。"]}>

地味だけど、便利です。Fat Modelを避けるために、責務に応じたオブジェクトを作る際に適用範囲は広いです。

🗻 あどがき

Ruby - Rails のアーキテクチャ設計を考える - Qiita」も勉強になる。
チームへの導入コスト等も考えつつ、検討していきたい!

🚕 参考リンク

📚 おすすめの書籍