Как извлечь реляционные данные из Rails DB в виде вложенного хеша? - PullRequest
0 голосов
/ 09 июля 2019

В моей базе данных Rails у меня есть следующие таблицы:

  • users
  • statuses (скажем, их имена включают active и inactive),
  • status_records для каждой даты для каждого пользователя, чтобы показать свой статус (например, date: '2019-07-09', user: User.first, status: Status.find_by(name: 'active')

Я хотел бы получить данные во вложенном хэше, например:

data = {
  "active"=>{
    "Rick"=>["2019-07-09", "2019-07-10"],
    "Morty"=>["2019-07-09", "2019-07-10"],
    "Summer"=>["2019-07-09", "2019-07-10"]
  },
  "inactive"=>{
    "Rick"=>["2019-07-01", "2019-07-02", "2019-07-03"],
    "Summer"=>["2019-07-15"]
  }
}

До сих пор я дошел до этого.

data = StatusRecord.joins(:status, :user)
  .where(statuses: {name: ['active', 'inactive']})
  .select('status_records.date, statuses.name as status, users.name as username')
  .group_by(|record| [record.status, record.username])

Вышеприведенное подводит меня к структуре данных ниже, но, как я уже писал ранее, это не совсем то, что я хочу (я хочуорганизовать данные как вложенный хэш).

data = {
  ["active", "Rick"]=>["2019-07-09", "2019-07-10"],
  ["active", "Morty"]=>["2019-07-09", "2019-07-10"],
  ["active", "Summer"]=>["2019-07-09", "2019-07-10"],
  ["inactive", "Rick"]=> ["2019-07-01", "2019-07-02", "2019-07-03"],
  ["inactive", "Summer"]=>["2019-07-15"]
}

Есть ли способ переписать этот запрос, чтобы я мог получить данные в нужной структуре?

Ответы [ 2 ]

0 голосов
/ 09 июля 2019

Вот чистое решение sql Обратите внимание, что это работает только с MySQL 5.7 + , но, возможно, существуют аналогичные решения для других баз данных.

    SELECT JSON_OBJECT(s.name, GROUP_CONCAT(srs.record)) AS record
    FROM statuses AS s
         INNER JOIN (SELECT JSON_OBJECT(u.name, GROUP_CONCAT(date)) AS record, status_id
                     FROM status_records AS sr
                              JOIN users u ON u.id = sr.user_id GROUP BY
                          u.id,
                          status_id) srs ON srs.status_id = s.id
    GROUP BY s.id;

Вы сможете проанализировать результирующий столбец записи каждой строки в хэш.

0 голосов
/ 09 июля 2019

Ты почти у цели!

Вы можете использовать Enumerable # each_with_object , чтобы немного исправить ваш вывод.

data = StatusRecord.joins(:status, :user)
  .where(statuses: {name: ['active', 'inactive']})
  .select('status_records.date, statuses.name as status, users.name as username')
  .each_with_object(Hash.new {|h,k| h[k] = Hash.new {|hh,kk| hh[kk] = [] } }) do |sr, hash|
    hash[sr.status][sr.username] << sr.date
  end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...