Могу ли я форсировать выполнение цепочки запросов активной записи? - PullRequest
0 голосов
/ 13 декабря 2018

У меня есть крайний случай, когда я хочу использовать .first только после того, как мой запрос SQL был выполнен.

Мой случай следующий:

User.select("sum((type = 'foo')::int) as foo_count",
            "sum((type = 'bar')::int) as bar_count")
    .first
    .yield_self { |r| r.bar_count / r.foo_count.to_f }

Однако это приведет к ошибке SQL, говорящей о том, что я должен включить свой user_id в предложение GROUP BY.Я уже нашел хакерское решение с использованием to_a, но мне действительно интересно, есть ли правильный способ принудительного выполнения перед моим вызовом .first.

Ответы [ 2 ]

0 голосов
/ 14 декабря 2018

Вы можете использовать pluck, который извлекает только данные вместо select, который просто изменяет, какие поля загружаются в модели :

User.pluck(
  "sum((type = 'foo')::int) as foo_count",
  "sum((type = 'bar')::int) as bar_count"
).map do |foo_count, bar_count|
  bar_count / foo_count.to_f 
end

Возможно, вы также можете выполнить деление в запросе.

0 голосов
/ 13 декабря 2018

Ошибка связана с тем, что first использует инструкцию order by, чтобы упорядочить по id.

"Найти первую запись (или первые N записей, если параметрЕсли заказ не определен, он будет заказываться по первичному ключу. "

Вместо этого попробуйте take

"Дает запись (или N записей, если указан параметр) без какого-либо подразумеваемого порядка. Порядокбудет зависеть от реализации базы данных. Если заказ будет предоставлен, он будет соблюден. "

Таким образом,

User.select("sum((type = 'foo')::int) as foo_count",
        "sum((type = 'bar')::int) as bar_count")
.take
.yield_self { |r| r.bar_count / r.foo_count.to_f }

должен работать надлежащим образом, как указано, заказ не определен.

...