Результат Mongoid Aggregate в экземпляре модели рельсов - PullRequest
0 голосов
/ 29 мая 2020

Введение

Исправляя устаревший код, существует индекс объекта LandingPage, в котором предполагается, что большинство столбцов можно сортировать, но это не так. В основном это было исправлено, но некоторые столбцы продолжают доставлять мне проблемы.

Эти столбцы требуют агрегирования, потому что они основаны на количестве других документов. Чтобы упростить объяснение проблемы, я расскажу только об одном из них, который называется Visit, так как остальной код будет просто дублироваться. каждый объект использует методы LandingPage перед отправкой json обратно. Это уже было так, и я не могу его изменить.

Из-за этого мне нужно выполнить агрегацию (отсортировать LandingPage по Visit счетчикам), а затем получить объект как LandingPage

Проблема заключается в невозможности преобразовать Mongoid :: Document в экземпляр LandingPage

Вот полученная мной ошибка:

Mongoid::Errors::UnknownAttribute:
Message:
  unknown_attribute : message
Summary:
  unknown_attribute : summary
Resolution:
  unknown_attribute : resolution

Вот мой код:

def controller_function
    landing_pages = fetch_landing_page 
    landing_page_hash[:data] = landing_pages.map do |landing_page|
        landing_page.do_something
        # Do other things
    end
    render json: landing_page_hash
end

def fetch_landing_page
    criteria = LandingPage.where(archived: false)

    columns_name = params[:columns_name]
    column_direction = params[:column_direction]

    case order_column_name
    when 'visit'
      order_by_visits(criteria, column_direction)
    else
      criteria.order_by(columns_name => column_direction).paginate(
                   per_page: params[:length],
                   page: (params[:start].to_i / params[:length].to_i) + 1
                 )
    end

    def order_by_visit(criteria, order_direction)


  def order_by_visits(landing_pages, column_direction)
      LandingPage.collection.aggregate([
          { '$match': landing_pages.selector },
          { '$lookup': {
              from: 'visits',
              localField: '_id',
              foreignField: 'landing_page_id',
              as: 'visits'
          }},
          { '$addFields': {  'visits_count': { '$size': '$visits' }}},
          { '$sort': { 'visits_count': column_direction == 'asc' ? 1 : -1 }},
          { '$unset': ['visits', 'visits_count'] },
          { '$skip': params[:start].to_i },
          { '$limit': params[:length].to_i }
      ]).map { |attrs| LandingPage.new(attrs) { |o| o.new_record = false } }
  end
end

То, что я пробовал

  • Скопируйте и вставьте ha sh в консоль в LandingPage.new(attributes) , и экземпляр был создан и действителен.
  • Измените ключ атрибутов со строки на символ, но он по-прежнему не работает.
  • Использование is_a?(hash) для любого элемента возвращенного массива возвращает правда.
  • Поместите его в json, а затем обратно в ha sh. По-прежнему есть Mongoid :: Document.

Как я могу сделать возвращение Aggregate действительным экземпляром LandingPage?

1 Ответ

0 голосов
/ 02 июня 2020

Конвейер агрегации реализуется драйвером Ruby MongoDB, а не Mongoid, и поэтому не возвращает экземпляры модели Mongoid.

Пример того, как можно получить экземпляры модели Mongoid, приведен в документация .

...