Rails - group_by - PullRequest
       44

Rails - group_by

8 голосов
/ 09 февраля 2011

В моем приложении есть несколько отчетов, и я пытаюсь создать вспомогательный метод для 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]

Любые подсказки о том, как сделать переменную "column" фактическим типом столбца во время выполнения, чтобы он считал себя столбцом activerecord, а не методом экземпляра?

Ответы [ 2 ]

21 голосов
/ 09 февраля 2011

Игнорируя некоторые другие проблемы в вашем коде, то, что вы пытаетесь сделать с column, можно сделать так:

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

Это работает, потому что в Ruby способ доступа к переменным экземплярачерез методы доступа, обычно именуемые по переменной, к которой вы пытаетесь обратиться, поэтому @item.foobar вызывает метод foobar для @item.

Теперь вернемся к этим "другим проблемам".Замечательно, что вы пытаетесь перенести повторяющееся поведение в одно место, и это показывает, что вы думаете о расширяемости, когда вы делаете вещи менее явными в пользу гибкости.Тем не менее, есть пара вещей, которые не очень хорошо сработают для вас, на что я вынужден указать.

  1. Группировка работает на множестве типов данных, большинство из которых не отвечают на strftime.Трудно кодируя вызов, вы вводите неожиданное поведение, которое означает, что вы не можете запустить group_collection(@users, :column => 'phone_number').Вместо этого запускайте его только после проверки того, что данные столбца могут на него реагировать.

    collection.group_by do |item|
      data = item.send(column)
      data.respond_to?(:strftime) ? data.strftime('%b %y') : data
    end
    
  2. Если вы определите поведение этого вспомогательного метода для группировки по произвольному столбцу, выможет исключить дополнительную сложность принятия хэша опций, только чтобы обойти его.

    def group_by_column(collection, column)
      collection.group_by { ... }
    end
    group_by_column(@users, :column)
    
  3. Вы можете сгруппировать по произвольному столбцу гораздо проще, если вы используете Ruby 1.9+и вам не нужно делать никакого дополнительного форматирования ..

    @users.group_by &:created_at
    
2 голосов
/ 09 февраля 2011
def group_collection(collection, options = {})
    column = options[:column]
    group_count = collection.group_by{ |item| item.send(column).strftime('%b %y')}
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...