Преобразование SQL в Arel или Squeel

tl;dr

Как преобразовать ниже SQL в Arel (или что-то, что считается стандартом в Rails)

@toplist = ActiveRecord::Base.connection.execute(
     'select ci.crash_info_id,
        count(distinct(user_guid))[Occurences], 
        c.md5 
      from crashes ci 
        join crash_infos c on c.id=crash_info_id 
      group by ci.crash_info_id
      order by [Occurences] desc')

--- конец tl;dr ----

Я работаю над небольшим веб-проектом, его цель — получить отчеты о сбоях наших клиентов (когда наше настольное приложение дает сбой, мы отправляем диагностику на наши серверы), анализировать их, а затем отображать наиболее распространенную ошибку, из-за которой наше приложение сбой.. Так что мы сосредоточимся на исправлении ошибок, которые затрагивают большую часть наших пользователей..

У меня есть 2 таблицы:

  1. crash_infos - id, md5 (md5 трассировки стека. В .net трассировка стека и сообщения об исключениях иногда переводятся .net на родной язык пользователя! Поэтому я в основном очищаю исключение, удаляя специфичные для языка части и создавая из него md5)

  2. сбои - id, user_guid (идентификатор пользователя), crash_info_id (идентификатор для таблицы crash_infos)

Теперь вопрос: я хотел сделать запрос, который показывает наиболее распространенные сбои для уникального пользователя (избегайте многократного подсчета одного и того же сбоя для одного и того же пользователя) и отсортировать его по количеству сбоев. К сожалению, я недостаточно знал Arel (или что-то еще, что такое ruby ​​on rails), поэтому в итоге я получил необработанный SQL :(

@toplist = ActiveRecord::Base.connection.execute(
  'select ci.crash_info_id,
     count(distinct(user_guid))[Occurences], 
     c.md5 
   from crashes ci 
   join crash_infos c on c.id=crash_info_id 
   group by ci.crash_info_id 
   order by [Occurences] desc')

Как я могу преобразовать это во что-то более «железное»?

заранее спасибо


person Jack Juiceson    schedule 08.12.2012    source источник


Ответы (1)


Не уверен, что это на самом деле лучше, но, по крайней мере, у вас должен быть независимый запрос к базе данных...

crashes     = Arel::Table.new(:crashes)
crash_infos = Arel::Table.new(:crash_infos)

crashes.
    project(crashes[:crash_info_id], crash_infos[:md5], Arel::Nodes::Count.new([crashes[:user_guid]], true, "occurences")).
    join(crash_infos).on(crashes[:crash_info_id].eq(crash_infos[:id])).
    group(crashes[:crash_info_id]).
    order("occurences DESC").
    to_sql

Дает:

SELECT "crashes"."crash_info_id", "crash_infos"."md5", COUNT(DISTINCT "crashes"."user_guid") AS occurences FROM "crashes" INNER JOIN "crash_infos" ON "crashes"."crash_info_id" = "crash_infos"."id" GROUP BY "crashes"."crash_info_id" ORDER BY occurences DESC
person Jiří Pospíšil    schedule 08.12.2012
comment
К сожалению, этот код выглядит еще сложнее, чем SQL. - person Jack Juiceson; 13.12.2012