Since the new deprecation policy the
composed_of removal was reverted. We are still discussing the future of this feature.
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 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.
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
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.