Как получить детали сгруппированного объекта - PullRequest
0 голосов
/ 24 сентября 2018

Я создаю приложение Rails 5, и в этом приложении я получил четыре модели.Пользователь, отчет, поездка и расходы.

Пользователь has_many Отчеты, поездки и расходы Отчеты has_many поездки и расходы.

Я хочу получить ответ JSON со всеми поездками и расходами, которые имеет пользовательсделано в этом месяце, сгруппировано по отчету.

Я могу сделать это, но мне нужны только идентификатор и заголовок отчета (при группировке), и теперь я получаю только имя объекта.

Я использую этот метод (находится в модели User):

def grouped_reports
    trips = self.trips
    expenses = self.expenses
    items = trips + expenses
    items.group_by(&:report)
  end

Вывод в формате JSON таков:

{
    "#<Report:0x007fa225163ba8>": [{
            "id": 12,
            "account_id": 20,
            "user_id": 92,
            "vehicle_id": null,
            "ttype": null,
            "description": "saf",
            "start_latitude": 57.4874919,
            "start_longitude": 12.0761927999999,
            "end_latitude": 59.3293235,
            "end_longitude": 18.0685808000001,
            "start_address": "Chicago",
            "end_address": "New york",
            "distance": 490,
            "time": null,
            "status": "pending",
            "registered_at": "2018-08-24T02:00:00.000+02:00",
            "approvals_count": 0,
            "rejections_count": 0,
            "created_at": "2018-08-24T22:39:22.637+02:00",
            "updated_at": "2018-08-24T22:39:22.637+02:00",
            "report_id": 79,
            "return_trip": null,
            "triptype_id": 10
        },
        {
            "id": 13,
            "account_id": 20,
            "user_id": 92,
            "cost": 100,
            "etype": null,
            "description": "sdsd",
            "start_address": null,
            "end_address": null,
            "distance": null,
            "reimbursable": false,
            "status": "pending",
            "registered_at": "2018-08-08T00:00:00.000+02:00",
            "created_at": "2018-08-24T22:39:40.343+02:00",
            "updated_at": "2018-08-24T22:39:40.343+02:00",
            "approvals_count": 0,
            "rejections_count": 0,
            "report_id": 79,
            "expensetype_id": 15
        }
    ]
}

Есть две вещи, которые мне нужно улучшить.

  • Отображать идентификатор и заголовок отчета нет.
  • Получать отчеты только за эти месяцы.

Обновление, это работает, но правильно ли это с точки зрения производительности?

И не только производительность, фактически ли оно использует заголовок отчета как фактор группировки?Что не очень хорошо, поскольку майские отчеты могут иметь одинаковый заголовок.Я хочу группировать по report_id, но отображать заголовок отчета.

def grouped_reports
    trips = self.trips
    expenses = self.expenses
    items = trips + expenses
    items.group_by{ |t| [t.report.id, t.report.title] }
  end

1 Ответ

0 голосов
/ 24 сентября 2018

Код будет отличаться в зависимости от того, какой формат JSON вы хотите вывести.

Я обычно использую генератор json, такой как jbuilder, но на этот раз я предлагаю массив и хэш-структуру.

class User < ApplicationRecord
  has_many :reports
  has_many :expenses
  has_many :trips

  def grouped_reports
    start_date = Time.current.beginning_of_month
    monthly_trips = trips.where('created_at >= ?', start_date)
    monthly_expenses = expenses.where('created_at >= ?', start_date)

    report_ids = (monthly_trips.map(&:report_id) + monthly_expenses.map(&:report_id)).uniq
    reports = Report.where(id: report_ids)

    reports.map do |report|
      {
        id: report.id,
        title: report.title,
        trips: trips.select {|t| t.report_id == report.id},
        expenses: expenses.select {|e| e.report_id == report.id}
      }
    end
  end
end
  1. Вы группируете с trips и expensesприсоединяется к одному массиву, но не желательно помещать разные типы в одни и те же массивы для JSON.Было бы безопасно иметь хеш-формат и отдельный ключ для trip и expense.
  2. Чтобы извлечь записи за этот месяц, используйте where для фильтрации.
  3. Возможнополучить trips, используя includes для reports и expenses, но с точки зрения производительности лучше сразу получить соответствующий trips.

Если вычтобы еще больше повысить производительность, сузьте только столбцы, используемые при выводе JSON с помощью метода select.Это было бы огромным улучшением, если бы выводилось много записей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...