2015-11-16 4 views
0

Допустим, у меня есть модель Account с колонками :email, :name, etc. Письма не уникальны. Я хочу добавить chainablescope, который выбирает строки с разными адресами электронной почты, но со всеми другими полями. Под «цепочкой» я имею в виду, что я мог бы так: Account.uniq_by_email.where(bla bla).Рельсы 4 Активная запись uniq по одному запросу столбца

Что я пробовал:

  1. С select:

    def self.uniq_by_email 
        select('distinct email') 
    end 
    

    Не работает для меня, как он выбирает только поле электронной почты.

  2. С group

    def self.uniq_by_email 
        group(:email) 
    end 
    

    это почти то, что я хочу: я могу цепь и он выбирает все поля. Но есть странная вещь о методе count: он, как вы уже догадались, возвращает хэш подсчета электронной почты. Но я хочу, чтобы он возвращал «простой» ActiveRecord_Relation, где count возвращает только счет, а не хэш. Этого можно достичь?

ответ

2

Моя основная идея - выбрать только первую запись в каждой группе писем. Сделать это легко, создать сферу, как это вместо того, чтобы использовать метод класса:

scope :uniq_by_email, -> { joins("JOIN (
            SELECT MIN(id) as min_id 
            FROM accounts 
            GROUP BY email 
           ) AS temp 
            ON temp.min_id = id") } 

Из этого вы можете сделать что-то вроде змеевидных как вы описали:

Account.uniq_by_email.where(bla bla) 
+0

Тх, что то, что я искал – nsave

1

Ну, вы можете использовать группу на, но и может считаться,

Account.uniq_by_email.where(bla bla).flatten.count 
+0

Да конечно, но это не является решением для меня. Этот 'uniq_by_email' используется для фильтрации нескольких шагов в зависимости от условий. Поэтому в конце запроса я не хочу выяснять, вызывался ли 'uniq_by_email' или нет. Я просто хочу получить количество найденных записей – nsave

Смежные вопросы