酒と泪とRubyとRailsと

Ruby on Rails と Objective-C は酒の肴です!

ActiveModelを使って、Classにバリデーションなどの便利機能を追加 [Rails4.2]

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


できること

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

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

実装例

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 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

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

1
2
3
4
5
6
7
8
# バリデーション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」も勉強になる。 チームへの導入コスト等も考えつつ、検討していきたい!

Special Thanks

おすすめの書籍