# 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 !
mainej
June 14, 2009, June 14, 2009 16:42, permalink
# 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
webandy.myopenid.com
June 24, 2009, June 24, 2009 00:02, permalink
Awesome, I made a module following your approach, thanks for your time.
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?