- loading...
map_by_method now works with ActiveRecord associations
I was always annoyed that map_by_method was broken for ActiveRecord has_many associations. 6 mths later I finally fixed it.
That’s the magic of Open Source Software. [/end sarcasm]
So now, the following example works like it should:
$ gem install map_by_method $ console > require 'map_by_method' # stick this in your environment.rb for Rails > user = User.find_by_name "Dr Nic" > user.companies.map_by_name => ['Dr Nic Academy', 'Dr Nic Institute of Being Silly'] > user.companies.map_by_id_and_name => [[1, 'Dr Nic Academy'], [9, 'Dr Nic Institute of Being Silly']]
Recap: why use map_by_method?
Try the following example:
> user.companies.map_by_employees.flatten => list of all employees of user
Versus:
> user.companies.map { |company| company.employees}.flatten
or
> user.companies.map(&:employees).flatten
Or compare:
> user.companies.map_by_id_and_name => [[1, 'Dr Nic Academy'], [9, 'Dr Nic Institute of Being Silly']]
Versus:
> user.companies.map { |company| [company.id, company.name]}
That is, it looks and feels just like ActiveRecord’s #find method, with its find_by_first_name_and_last_name magic.
Summary
No {, }, |, &, or : required. Just clean method names.
Bonus other gem
In the spirit of ActiveRecord hacks, there is to_activerecord:
$ gem install to_activerecord $ console > require 'to_activerecord' # stick this in your environment.rb for Rails > [1,2,3].to_user => [list of User with id's 1,2,3]
To me, this suffix operator reads cleaner than the traditional:
> User.find([1,2,3])
For example, if you want to perform an operation on the list of Users:
> ids = [1,2,3] > ids.to_user.map_by_name => ['Dr Nic', 'Banjo', 'Nancy']
Versus:
> User.find(ids).map_by_name
Related posts:
- map_by_method – the final announcement I don’t really talk about my projects after I release...
- Welcome to the future Welcome to anyone visiting from DHH’s blog and other corners...
- “Drop Rails into TomCat and it just works” – Ola Bini on JRuby presentation Until Ola Bini stood up at the Stockholm Rails/Ruby Group...
- map_by_method now increasingly more niftier-er. Recap on map_by_method magic: >> p.account.transfers.map_amount # amount method mapped...
- [ANN] Generating new gems for graceful goodliness I don’t like you [1]. You don’t share code....
Trackbacks
Use this link to trackback from your own site.





I am not convinced !
versus
I do not see such a difference compared to the method_missing time we lose here.
[start jedi mind trick] That’s not the example you are looking for[/end trick]
I agree that example isn’t the best, so how about this one:
The Symbol.to_proc cannot be used here, so you are left with:
user.companies.map {|company| [company.id, company.name, company.employees}I’d also argue that:
is more readable and concise than:
Readability is higher in book any day.
Great work once again Dr.Nic!
‘map_by_id_and_name’ looks made for the select form helper. One less model-method to hand make!
Nice one!
good stuff. i was looking for magic like this just the other day.
Great stuff, as always. Just wanted to point out that “map_by_method” link in the first line of your post, is broken.
@chris [via] – ok, I’ve fixed the link, but just to make sure, can you click the links harder next time?
Nic,
Is there something going on with map_by_method and ActionController For some reason it looks like any of my RESTful actions are failing; even if I don’t require ‘map_by_method’ in the environment. I get something like :
NoMethodError (undefined method `to_str’ for [:action, "index"]:Array):
/usr/local/lib/ruby/gems/1.8/gems/map_by_method-0.7.0/lib/map_by_method.rb:12:in `method_missing’
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/layout.rb:241:in `to_s’
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/layout.rb:241:in `render_without_benchmark’
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/lib/action_controller/benchmarking.rb:50:in `render’
Or does it somehow extend Array that ActionController doesn’t like? As great as it would’ve been to use it, I had to uninstall 0.7.0, sorry… let me know if you want to see of the rest of the log….
@Vann [via] – I noticed a similar problem around the active_record_store.rb just a little while ago. I’ll post an update when I fix it. My initial thought is that its the added #respond_to? method in 0.7. Anyway, still investigating.
So much magic in so many places.
@Vann [via] – as for “even if I don’t require ‘map_by_method’” – you might have this in your .irbrc file perhaps.
@dr nic …I actually do have it in my .irbrc file, I’ll remove it from there and let you know if anything is fixed. But does it matter unless you run anything in the console?
[...] map_by_method now works with ActiveRecord associations. [...]
@Dr Nic [via]
-
Great module Dr Nic!
I only had some trouble with the regex for the ‘respond_to?’ method.
The regex in map_by_method_regex is:
/(map|collect|select|each|reject)(_by)?_([\w\_]+\??)/
which does (unfortunately) also match ‘each_pair’. This caused some trouble in my app since an array responds to a method that belong to hashes. Removing the ‘?’ after ‘(_by)’ in the regex works for me.
@Dr Nic [via] – Yeah, ok, but only in Rails does this make a difference. It seems pretty specific to the Rails domain of homogeneous arrays of model objects, readable-as-English code, and the need for blazing-fast development.
With those as givens, of course, this is pretty neat.
Any progress on the issue reported by Vann above? Ran into this too, and had to downgrade back to 0.6.0.
Symbol#to_proc can also be used with all the enumerable methods that take blocks, like sort_by and select.
@mike [via] – true, I need to explicitly add them into the map_by_method code for them to work.
Regarding the 0.7.0 issue with Rails, its something to do with the respond_to? method I added. I’m still to investigate.
All known issues are resolved in 0.8.1. Thxs to Mislav Marohnić for hunting down some of the issues!
Except the each_pair issue. I’ll investigate this later.
map_by_method 0.8.2 should fix the each_pair issue
[...] map_by_method now works with ActiveRecord associations [...]