Rails - group_by

发布于 2024-10-16 23:17:34 字数 527 浏览 6 评论 0原文

我的应用程序有一些报告,我正在尝试为所有这些集合的 group_by 制作一个辅助方法。

示例:

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

这就是我计划使用它的方式

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

不幸的是,这不起作用。

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

关于如何在运行时使“列”变量成为实际列类型的任何线索,以便它认为自己是 activerecord 列而不是实例方法?

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")

Unfortunately, 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

稚气少女 2024-10-23 23:17:34

忽略代码中的一些其他问题,您尝试使用 column 执行的操作可以像这样完成:

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

这是可行的,因为在 Ruby 中,访问实例变量的方式是通过访问器方法,通常以您尝试访问的变量,因此 @item.foobar 调用 @item 上的 foobar 方法。

现在,回到那些“其他问题”。尝试将重复的行为转移到一个地方是件好事,并且当您为了灵活而让事情变得不那么明确时,这表明您正在考虑可扩展性。然而,有一些事情对你来说不太好,我觉得有必要指出。

  1. 分组适用于许多数据类型,其中大多数不响应 strftime。通过对调用进行硬编码,您会引入意外行为,这意味着您无法运行group_collection(@users, :column => 'phone_number')。相反,只有在测试列数据可以响应它之后才运行它。

    collection.group_by 做 |item|
      数据 = item.send(列)
      data.respond_to?(:strftime) ? data.strftime('%b %y') : 数据
    结尾
    
  2. 如果您确定此辅助方法的行为是在任意列上进行分组,则您可以放弃接受选项哈希的额外复杂性,而只是为了规避它。

    def group_by_column(集合,列)
      集合.group_by { ... }
    结尾
    按列分组(@用户,:列)
    
  3. 如果您使用的是 Ruby 1.9+ 并且不需要进行任何额外的格式化,您可以更轻松地按任意列进行分组。

    @users.group_by &:created_at
    

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
    
冷情 2024-10-23 23:17:34
def group_collection(collection, options = {})
    column = options[:column]
    group_count = collection.group_by{ |item| item.send(column).strftime('%b %y')}
end
def group_collection(collection, options = {})
    column = options[:column]
    group_count = collection.group_by{ |item| item.send(column).strftime('%b %y')}
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文