- loading...
map_by_method now increasingly more niftier-er.
Recap on map_by_method magic:
>> p.account.transfers.map_amount # amount method mapped to all Transfers => [1878.35, 433.0, 433.0, 433.46, 433.46, 433.46, 433.46, 433.46, 300.0, 300.0] >> p.account.transfers.map_date.map_to_s # date method mapped to all Transfers, and the Dates mapped into strings => ["2003-05-27", "2003-06-23", "2003-06-27", "2003-07-04", "2003-07-11", "2003-07-18", "2003-07-25", "2003-08-08", "2003-09-25", "2003-10-03"]
But if you want the amount and date methods mapped at the same you’ve been plain out of luck, and forced to use the uglier block syntax:
>> p.account.transfers.map {|t| [t.amount, t.date]}
Due to demand-by-inspiration (that is, I just thought of it), you can now use _and_ to join method names together, thusly:
>> p.account.transfers.map_date_and_amount [[#<Date: 4905573/2,0,2299161>, 1878.35], [#<Date: 4905627/2,0,2299161>, 433.0], [#<Date: 4905635/2,0,2299161>, 433.0], [#<Date: 4905649/2,0,2299161>, 433.46], [#<Date: 4905663/2,0,2299161>, 433.46], [#<Date: 4905677/2,0,2299161>, 433.46], [#<Date: 4905691/2,0,2299161>, 433.46], [#<Date: 4905719/2,0,2299161>, 433.46], [#<Date: 4905815/2,0,2299161>, 300.0], [#<Date: 4905831/2,0,2299161>, 300.0]] >> p.account.transfers.map_date_and_amount.map_map_to_s [["2003-05-27", "1878.35"], ["2003-06-23", "433.0"], ["2003-06-27", "433.0"], ["2003-07-04", "433.46"], ["2003-07-11", "433.46"], ["2003-07-18", "433.46"], ["2003-07-25", "433.46"], ["2003-08-08", "433.46"], ["2003-09-25", "300.0"], ["2003-10-03", "300.0"]]
Note the dubious/amusing use of map_map_to_s to apply to_s to the inner arrays. That is, map_to_s is mapped to each inner array.
Want this extended map_by_method magic? Version 0.5 of map_by_method is ready via gem install map_by_method now (or direct download)
Bonus use
Make simple arrays for drop-down lists based on id and a string name field of a list of objects.
>> User.find(:all).map_id_and_firstname => [[1, "Glenda"], [2, "Brenda"], [3, "Yas"], [4, "Osborne"], [5, "Gary"], [6, "Anthony"], [7, "Jackie"]]
Debugging use
Some of my Transfer rows had amounts of zero. This was just stupid, but as the initial data was being migrated from a variety of sources I needed to figure out where it was coming from.
“I wonder which account owner(s) this erroneous data comes from?”
> zero_transfers = Transfer.find(:all,:conditions => ['amount < 10 and amount > -10'])
> zero_transfers.map_from_account.map_owner.map_name
["Brenda",
"Brenda",
"Brenda",
"Brenda",
"Brenda"]
And I now knew which files to start cleaning up before re-importing all the data again.
Data investigation in the console/irb becomes almost fun.
Related posts:
- map_by_method – the final announcement I don’t really talk about my projects after I release...
- map_by_method now works with ActiveRecord associations I was always annoyed that map_by_method was broken for ActiveRecord...
- Welcome to the future Welcome to anyone visiting from DHH’s blog and other corners...
- [ANN] Generating new gems for graceful goodliness I don’t like you [1]. You don’t share code....
- I love “map by pluralisation” [now: map_by_method] Update: this is a gem called map_by_method. The other day...
Oh crap, I come up with one good idea and you had to beat me to it.
http://dashing.com/blog/2006/12/09/super_easy_collect_for_activerecord_arrays
Keep up the great work!
Cheers,
John
@john – dude, we could play “Code Jinx” – for two people who right the same chunk of code
Perhaps I’m being dull, but can’t you just do the first one like:
p.account.transfers.map(&:amount)
?
@ben: yep that’ll get you the same thing, and I think the Symbol.to_proc solution you’ve got there is going into/has gone into Ruby core itself.
For me, its too many funny characters (2 brackets, an ampersand, and a colon), and it doesn’t extend to mapping 2+ methods on the objects in the array.
The upside of the
map(&:amount)syntax is you don’t need to invoketo_aon the associations.I should get around to fixing that so the association proxy supports the map_by_method idea too.
Hello,
I’m having a problem with the map_by_method gem. I don’t understand why, but when I require it from ~/.irbrc, it does not actually get required – *and* any require statements I have after it also seem to have no effect.
However, when I require it manually from a rails console, it works fine.
All I am saying in .irbrc is:
require ‘map_by_method’
which is exactly the same thing I say in the console when I do it manually, and it works. Any help would be appreciated.