LoginSignup
80
79

More than 5 years have passed since last update.

ActiveModelを活用するための属性定義拡張系gemについて

Last updated at Posted at 2014-08-21

ActiveModelをベースにしたモデルクラスやFormオブジェクトを作ってると、attribute定義を沢山書くことになります。
その際に、セットで考えなきゃいけないのは、タイプキャスト、デフォルト値、初期化方法です。

で、この辺りを楽にしたいと考える人は大勢居るもので、これらの定義を楽にしてくれるgemがいくつかあります。

今日、いくつかチェックしたので軽くまとめておきます。

active_attr, virtus

active_attrとvirtusは、ActiveModel::ModelがRailsに入る前からActiveRecordっぽいインターフェースを持ったオブジェクトを定義しやすいように、モジュール自前で色々持ってます。
更に値を代入した時に、良しなにタイプキャストしてくれたり、オブジェクトをinitializeした時にデフォルト値を自動で代入してくれる機能なんかがあります。

active_attr
class Person
  include ActiveAttr::TypecastedAttributes
  attribute :age, :type => Integer
end

person = Person.new
person.age = "29"
person.age #=> 29
virtus
class Page
  include Virtus.model

  attribute :title, String

  # default from a singleton value (integer in this case)
  attribute :views, Integer, :default => 0

  # default from a singleton value (boolean in this case)
  attribute :published, Boolean, :default => false

  # default from a callable object (proc in this case)
  attribute :slug, String, :default => lambda { |page, attribute| page.title.downcase.gsub(' ', '-') }

  # default from a method name as symbol
  attribute :editor_title, String,  :default => :default_editor_title

  def default_editor_title
    published? ? title : "UNPUBLISHED: #{title}"
  end
end

page = Page.new(:title => 'Virtus README')
page.slug         # => 'virtus-readme'
page.views        # => 0
page.published    # => false
page.editor_title # => "UNPUBLISHED: Virtus README"

page.views = 10
page.views                    # => 10
page.reset_attribute(:views)  # => 0
page.views                    # => 0

virtusはinclude方法とかコンフィグの書き方に若干癖がありますが、こっちの方が開発が活発で人気っぽいです。

active_attrは、activemodelとactivesupportに依存しているため、railsのmasterを使ってバージョンアップの準備等をする際には邪魔になる可能性があります。

attorio

attorioはactive_attrとvirtusの属性定義部分に特化したgemです。
後発で、コードベースがコンパクトです。外部に依存するgemを一切持たずに単体で完結してるのがウリらしいです。
typecastの動作が分かり易くて、この辺カスタマイズはし易そうなんですが、コミットはそんなに活発じゃないようです。
後、ロシア語圏の人が作ってるのか一部のissueが全然読めませんw

attorio
class User
  include Attrio

  define_attributes :as => 'api_attributes' do
    attr :name, String
    attr :age, Integer
    attr :birthday, DateTime
  end

  define_attributes :as => 'settings' do
    attr :receives_notifications, Boolean, :default => true
  end

end

ざっくりコードを読んだ所、attributesを定義したら、self.inheritedを勝手に上書きしてしまうらしく、これちょっとまずいんじゃないのか?みたいな箇所があります。
軽量なんで、ハマったら自力で何とかできる余地はありますが。

attr_extras

他のgemとはちょっと違って、attr_accessorっぽい記述で色々機能追加したアクセサを定義できるgemです。
プライベートなアクセサを定義するattr_privateや初期化機能付きのアクセサを定義するattr_initialize、値オブジェクトの定義を支援してくれるattr_valueなんかが追加されます。

80
79
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
80
79