У меня в рельсах такой запрос:

records = Record.select('y_id, source')
                .where(:source => source, :y_id => y_id)
                .group(:y_id, :source)
                .having('count(*) = 1')

Я получаю следующий результат, если puts records:
[#<Record source: "XYZ", y_id: 10000009>, #<Record source: "XYZ", y_id: 10000070>]

Похоже, что в выходном массиве 2 элемента. Но когда я пытаюсь сделать records.size, я получаю:
{[10000009, "XYZ"]=>1, [10000070, "XYZ"]=>1}

  • Почему records.size не печатает 2, если записи представляют собой массив из двух элементов? Результат запроса group by по какой-то причине ведет себя иначе?

  • Что мне делать, чтобы получить размер records

3
Atri 31 Дек 2015 в 06:53

3 ответа

Лучший ответ

Я мог ошибиться, но думаю, проблема в том, как работает .size.

Размер автоматически попытается определить, следует ли вызывать .count или .length. Они ведут себя следующим образом:

  • .count выполняет SQL COUNT
  • .length вычисляет длину результирующего массива

Однако в некоторых случаях .size возвращает хэш (поскольку он решил использовать .count)

Таким образом, ваше решение может заключаться в использовании .length, которое вернет целое число.

6
Ben Hawker 31 Дек 2015 в 04:31

Я просто попробовал вариант из приведенного выше примера (с использованием моего собственного существующего приложения Rails и БД), и он работал без проблем:

records = Site.select('name','url')
    .where(:name => 'Washington Post', :url => 'https://www.washingtonpost.com/')
    .group(:name, :url)
    .having('count(*) = 1')

 => #<ActiveRecord::Relation [#<Site id: nil, name: "Washington Post", url: "https://www.washingtonpost.com/">]> 

records.size

 => 1 

Вы уверены, что ваша модель записи наследуется от ActiveRecord::Base?

0
jayp 31 Дек 2015 в 04:31

Получить его можно с помощью:

results.length

Метод размера использует метод подсчета sql, который ведет себя таким образом.

3
Triveni Badgujar 31 Дек 2015 в 04:32