Avatar

Hello. This is from my blogging app. I'd like to extract a private method that would call group_by for an array of items passed to it, and take a method argument for what to group the records by. At least the first two code lines are exactly the same. I tried using eval() but was unsuccessful at passing a method argument in to be used within the group_by block. any help?

1
2
3
4
5
6
# stats is an array

@popular_urls = stats.group_by{|s| s.request_uri}.sort_by {|s| s.second.size}.reverse
@referrers = stats.group_by{|s| s.referrer}.sort_by {|s| s.second.size}.reverse
@ip_addresses = stats.reject{|s| s.remote_ip.blank?}.group_by{|s| s.remote_ip}.sort_by {|s| s.second.size}.reverse
@searches = Search.all.group_by{|s| s.query}.sort_by {|s| s.second.size}.reverse # FIXME go through site.searches association

Refactorings

No refactoring yet !

Avatar

mainej

June 14, 2009, June 14, 2009 16:42, permalink

No rating. Login to rate!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# You can factor out the common aspects:

module Popularity
  def rank_by
    group_by {|e| yield e }.sort_by {|e| -e.second.size }
  end
end

# Then the question is, how intrusive do you want it to be?  You can use it 
# as you need it:

stats.extend Popularity
@popular_urls = stats.rank_by {|s| s.request_uri }
@referrers    = stats.rank_by {|s| s.referrer }

@ip_addresses = stats.reject {|s| s.remote_ip.blank? }.extend(Popularity).rank_by {|s| s.remote_ip }

@searches = Search.all.extend(Popularity).rank_by {|s| s.query }

# Or if you use the pattern regularly, you can make it available (almost?) 
# everywhere, at the expense of monkey-patching Array.

class Array; include Popularity; end

@popular_urls = stats.rank_by {|s| s.request_uri }
@referrers    = stats.rank_by {|s| s.referrer }
@ip_addresses = stats.reject {|s| s.remote_ip.blank? }.rank_by {|s| s.remote_ip }
@searches     = Search.all.rank_by {|s| s.query } # Untested - not sure if AR proxies get all Array methods
Avatar

webandy.myopenid.com

June 24, 2009, June 24, 2009 00:02, permalink

No rating. Login to rate!

Awesome, I made a module following your approach, thanks for your time.

Your refactoring





Format Copy from initial code

or Cancel