开发者

Rails - group_by

My application has a few reports and I'm trying to make a helper method for group_by for all these collections.

Example:

def group_collection(collection, options = {})
    column = options[:column]
    group_count = collection.group_by{ |item| item.column.strftime('%b %y')}
end

This is how i plan to use it

@user_groups = group_collection(@users, :column => "created_at")

Unfortunate开发者_JAVA百科ly, this does not work.

undefined method `column' for... [CollectionObject]

Any clues on how to make the "column" variable an actual column type at runtime so it considers itself as activerecord column and not a instance method?


Ignoring some of the other problems in your code, what you are trying to do with column can be done like so:

collection.group_by { |item| item.send(column).strftime('%b %y') }

This works because in Ruby the way you access instance variables is through accessor methods, usually named after the variable you're trying to access, so @item.foobar calls the foobar method on @item.

Now, back to those "other problems". It's great that you're trying to move repeated behavior into a single place, and it shows you're thinking about extensibility when you make things less explicit in favor of being flexible. However, there are a couple of things that aren't going to work out very well for you here that I feel compelled to point out.

  1. Grouping works on lots of data types, most of which don't respond to strftime. By hard coding the call to it you're introducing unexpected behavior that means you can't run group_collection(@users, :column => 'phone_number'). Instead, only run that after testing that the column data can respond to it.

    collection.group_by do |item|
      data = item.send(column)
      data.respond_to?(:strftime) ? data.strftime('%b %y') : data
    end
    
  2. If you nail down the behavior of this helper method is to group on an arbitrary column, you can ditch the additional complexity of accepting an options hash, only to circumvent it.

    def group_by_column(collection, column)
      collection.group_by { ... }
    end
    group_by_column(@users, :column)
    
  3. You can group by an arbitrary column much more easily, provided you're using Ruby 1.9+ and you don't need to do any additional formatting..

    @users.group_by &:created_at
    


def group_collection(collection, options = {})
    column = options[:column]
    group_count = collection.group_by{ |item| item.send(column).strftime('%b %y')}
end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜