Alexander Presber
Alexander Presber

Reputation: 6635

ActiveRecord::Type::Value casting in Rails 4

We want to use the Whole Value pattern in our Rails4 application.

We know that in Rails5, if we want OurModel to use a custom NameType Whole Value type for the attribute :name, we can define our custom type similar to this:

class NameType < ActiveModel::Type::Value
  def cast(value)
    Name(value)
  end

  def serialize(value)
    value.to_s
  end
end

and then in OurClass

class OurClass < ApplicationRecord
  attribute :name, NameType.new
  ...
end

which provides us with completely transparent serialization when saving the model to the DB and casting to the Whole Value Type when creating the model from the DB or manually (this is described in this RubyTapas episode, subscriber-only).

Can something similarly elegant be achieved in Rails 4? If so, how?

Upvotes: 1

Views: 629

Answers (1)

pgaspar
pgaspar

Reputation: 143

In this video David Copeland uses a slightly different approach using serialize but that ends up with a very similar effect, I believe.

class OurClass < ApplicationRecord
  serialize :name, Name
  ...
end

Then your whole value (or a proxy class like NameType) needs to include the load and dump methods to adhere to the serializable interface:

class Name
  ...
  def self.load(value)
    self.new(value)
  end

  def self.dump(name)
    name.to_s
  end
end

You can then use the name attribute with the Name whole value:

OurClass.new(name: 'a name').name # => A Name instance
OurClass.find_by(name: Name.new('a saved name')).name # => A Name instance

Upvotes: 1

Related Questions