Attributes

attributes acts as a way to add a typecast layer to a model. The attribute may be backed by a database column, or it can be a "transient" attribute that only exists for the lifetime of a model instance.

Also see store_model.

Use cases

Structured JSON

JSON columns can be very lightweight and flexible ways to represent data when you are not sure exactly what you schema will look like in the future, and can be a way to defer decision making until more information is known. Adding a custom type and an attribute to represent a JSON column can provide more robustness.

This can look like this:

# In some model...
attribute :my_custom_attribute, Attributes::MyCustomAttribute.new
# The "bridge" between the attribute definition and the custom attribute type
class Attributes::MyCustomAttribute < ActiveRecord::Type::Json
  def deserialize(value)
    return value unless value.is_a?(String)

    parsed = JSON.parse(value)

    if parsed.blank?
      return MyCustomAttribute.new
    end

    MyCustomAttribute.new(**parsed.symbolize_keys)
  end

  def serialize(value)
    value&.to_json
  end
end
# An ActiveModel-enabled class that can run validations, define custom comparators, etc.
class MyCustomAttribute
  include ActiveModel::Model
  include ActiveModel::Validations

  # ...definitions
end

Sources

Last updated