{"id":2841,"date":"2012-06-20T11:53:56","date_gmt":"2012-06-20T14:53:56","guid":{"rendered":"http:\/\/blog.plataformatec.com.br\/?p=2841"},"modified":"2012-08-13T17:16:25","modified_gmt":"2012-08-13T20:16:25","slug":"about-the-composed_of-removal","status":"publish","type":"post","link":"https:\/\/blog.plataformatec.com.br\/2012\/06\/about-the-composed_of-removal\/","title":{"rendered":"About the composed_of removal"},"content":{"rendered":"

Update 08\/13\/2012<\/h3>\n

Since the new deprecation policy<\/a> the composed_of<\/code> removal was reverted. We are still discussing the future of this feature.<\/p>\n

The reason<\/h3>\n

A few days ago we started a discussion about the removal of the composed_of<\/code><\/a> method from Active Record. I started this discussion because when I was tagging every Rails issue according to its framework, I found some<\/a> of them<\/a> related<\/a> to composed_of<\/code><\/a>, 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.<\/p>\n

In this presentation<\/a>, Aaron Patterson<\/a> 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<\/code>. 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.<\/p>\n

The plan<\/h3>\n

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.<\/p>\n

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.<\/p>\n

Implementation<\/h3>\n

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<\/code> feature with a custom serializer:<\/p>\n

\nclass MoneySerializer\n  def dump(money)\n    money.value\n  end\n\n  def load(value)\n    Money.new(value)\n  end\nend\n\nclass Account < ActiveRecord::Base\n  serialize :balance, MoneySerializer.new\nend\n<\/pre>\n

To use it with multiple attributes you can do the following:<\/p>\n

\nclass Person < ActiveRecord::Base\n  def address\n    @address ||= Address.new(address_street, address_city)\n  end\n\n  def address=(address)\n    self[:address_street] = address.street\n    self[:address_city]   = address.city\n    \n    @address = address\n  end\nend\n<\/pre>\n

Benefits for Rails developers<\/h3>\n

I already talked about what this removal can provide to Rails maintainers, but what benefits does it bring to Rails developers?<\/p>\n

I think that the best advantages are:<\/p>\n