Update 08/13/2012

Since the new deprecation policy the composed_of removal was reverted. We are still discussing the future of this feature.

The reason

A few days ago we started a discussion about the removal of the composed_of method from Active Record. I started this discussion because when I was tagging every Rails issue according to its framework, I found some of them related to composed_of, that are not only hard to fix but would add more complexity for a feature that, in my opinion, is not adding any visible value to the framework.

In this presentation, Aaron Patterson talks about three types of features: Cosmetic, Refactoring, and Course Correction. Aaron defines cosmetic features as a feature that adds dubious value and unknown debt (I highly recommend that you watch the whole presentation to see more about these types of features). This is exactly what I think about composed_of. At this time this feature is adding more debt than value to the Rails code base and applications, so the Rails team have decided to remove this method.

The plan

The removal plan is simple, deprecate in 3.2 and remove in 4.0. This means that you need to stop using this feature and implement it in another way.

The Rails team have chosen this path because this feature can be implemented using plain ruby methods for getters and setters. You will see how in the next section.

Implementation

In the simplest case, when you have only one attribute and needs to instantiate an object with the value of this attribute, you can use the serialize feature with a custom serializer:

class MoneySerializer
  def dump(money)
    money.value
  end
 
  def load(value)
    Money.new(value)
  end
end
 
class Account < ActiveRecord::Base
  serialize :balance, MoneySerializer.new
end

To use it with multiple attributes you can do the following:

class Person < ActiveRecord::Base
  def address
    @address ||= Address.new(address_street, address_city)
  end
 
  def address=(address)
    self[:address_street] = address.street
    self[:address_city]   = address.city
 
    @address = address
  end
end

Benefits for Rails developers

I already talked about what this removal can provide to Rails maintainers, but what benefits does it bring to Rails developers?

I think that the best advantages are:

  • It is easier to test the composite objects;
  • It is easier to understand the lazy methods;
  • It is easier to customize it without resorting to options like :converter, :constructor and :allow_nil.

Wrapping up

I strongly recommend that you read the whole discussion in the pull request. You will find more examples and additional information there.

Also, I want to thank @steveklabnik for working on this feature and the awesome work that he has been doing on the Rails Issues Team.

Finally, I want to invite you to help the Rails team to fix, test, and track issues. About half of the issues are related to the Active Record framework and we need to work on them. As a regular Rails contributor and Rails developer, I think there is still a lot we can do to improve the Rails code base, so join us.

Tags: , ,

This entry was posted on Wednesday, June 20th, 2012 at 11:53 am and is filed under English. You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.

Comments are closed.