LoginSignup
104
84

More than 3 years have passed since last update.

ActiveModel::Attributesを使う

Last updated at Posted at 2019-12-19

ここでは、Rails 5.2で導入されたActiveModel::Attributesについて紹介します。RubyのクラスにActiveRecordのカラムのような属性を加えられます。

サンプル:
https://github.com/kazubon/blog-rails6-vuejs/blob/master/app/forms/entries/form.rb

クラスにActiveModel::ModelとともにActiveModel::Attributesをインクルードします。

class Entries::Form
  include ActiveModel::Model
  include ActiveModel::Attributes

クラスメソッドattributeに属性名と型を渡すと、attr_accessorと同じように属性が使えるようになります。指定できる型の種類については、Railsのソースを直接参照してください。

attributeをクラスの冒頭に並べておくと、「このクラスは何をパラメータとして受け取るのか」を明示できるというメリットもあります。なお、この例のtagsは配列で、指定できる型がないので型を指定していません。

  attribute :title, :string
  attribute :body, :string
  attribute :draft, :boolean, default: false
  attribute :published_at, :datetime
  attribute :tags

defaultオプションで初期値を指定できます。Procも指定できます。

  attribute :published_at, :datetime, default: ->{ Time.now }

属性を使うには、superでActiveModel::Attributesのinitializeメソッドを呼び出す必要があります。

  def initialize(user, entry, params = {})
    @user = user
    @entry = entry
    super(params)
  end

このsuper(params)は次のように置き換えても同じです。

    @attributes = self.class._default_attributes.deep_dup
    assign_attributes(params)

ActiveRecordのカラムと同じく、attributeで加えた属性に値を入れると、数値、時刻、ブーリアンのような型に合わせて値が変換されます。時刻(:datetime)では次のような感じです。

  form.published_at = "2019/12/19 12:30"
  form.published_at #=> 2019-12-19 12:30:00 +0900
  form.published_at = "xxxxx"
  form.published_at #=> nil

ブーリアン(:boolean)では、[false, 0, "0", :"0", "f", :f, "F", :F, "false", :false, "FALSE", :FALSE, "off", :off, "OFF", :OFF] が false、それ以外は true になります。空文字列はnilになります。

  form.draft = "1"
  form.draft #=> true
  form.draft = "0"
  form.draft #=> false

インスタンスメソッドattributesで「属性名 => 値」のハッシュが取り出せます。

form.attributes
#=> {"title"=>"Foo", "body"=>"bar", "draft"=>false, "published_at"=>2019-12-15 15:40:00 +0900, "tags"=>["Ruby", "Rails"]}

インスタンスメソッドまたはクラスメソッドのattribute_namesで属性一覧が取り出せます(Rails 6で追加)。

form.attribute_names
#=> ["title", "body", "draft", "published_at", "tags"]

以上です。

ActiveModel::Attributes を使わずに型キャストをしたいときは、 ActiveRecord以外で型キャストを使う を参照しくてください。

104
84
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
104
84