Stephen Chu talked about how to beautify statements like
customers.collect { |customer| customer.name }
in one of his posts. Dr. Nic also has a post talking about the same thing. It’s very interesting to see so many people want to get away the cumbersome collect syntax and I am one of these people.
To beautify the collect syntax when we need just one field such as customer.name
. There are several ways:
to use Stephen’s syntax:
customers.collect_name
Dr. Nic’s:
customers.names
And guess what, if you are using Rails, it comes with a Symbol extension method called to_proc
. What the method does is to turn a symbol into a simple Proc object. so we can say:
customers.collect &:name
which does the job.
In practice, I always just use this built-in to_proc because it’s free as long as you are on a Rails project. And there is no reason for me to justify I should spend time to make it even more magical.
Stephen also came up with syntax like:
customers.collect_name_and_id
The method always returns an array of arrays ([['Yi', 1], ['Du', 2]]
). The syntax looks very nice, but I think it has limited value because I may not want an array of arrays, I may want an array of hashes ([{1 => 'Yi'}, {2 => 'Du']
), or an array of strings, then the method has no use or we have to do more magic. Most importantly, when we want multiple fields from a model object to form some kind of data structure, we probably should ask ourselves first: what’s the business meaning for this action? If we can find one, we can just add one method, returning whatever we want, to the model class we are dealing with and use that method for collect.
For example, if I want to send an email to several people and their email address should look like:
people.collect{|person| "person.name <person.email>"}
, then I probably will just add a method to the Person class, such as Person#full_email_address
and return the string I need. the the syntax for collect can be simplified to people.collect &:full_email_address
.
It’s cool to see how powerful method_missing
can be with Stephen’s extension, and how lovely Ruby is.
Posted in ruby on rails
Tags: ruby on rails