Rails AMS, укажите разные сериализаторы в полиморфном списке

Я реализовал поиск по нескольким таблицам с помощью pg_search, а затем сериализовал результат с помощью Active Model Serializer (версия 0.10) — он работает нормально, но AMS использует сериализатор по умолчанию для каждого из возвращаемых типов.

Вот сериализатор:

class SearchBarSerializer < ApplicationSerializer
  attributes :searchable_type
  belongs_to :searchable
end

Так, например, при сериализации объектов, возвращенных из pg_search, если соответствующий объект является «Пользователь», тогда AMS использует UserSerializer. Если релевантным типом является лига, то AMS использует LeagueSerializer.

Это нормально, но я хотел бы использовать разные сериализаторы для каждого типа. Это для панели поиска, поэтому меня интересует гораздо меньший объем данных, чем полный стандартный сериализатор. (EDIT: стандартные сериализаторы сериализуют все атрибуты и ассоциации для каждой из моделей User и League, что можно увидеть ниже. Каждая модель несколько значительно больше, и для целей простого поиска мне действительно нужно только имя каждой модели и id и, возможно, некоторые другие более мелкие данные для каждого типа)

Есть ли способ указать, какой сериализатор использовать в зависимости от объекта?

Благодарю вас!

РЕДАКТИРОВАТЬ:

Модель пользователя:

class User < ActiveRecord::Base
  include PgSearch

  #################### Associations
  has_and_belongs_to_many :roles
  belongs_to :profile_page_visibility, optional: true # the optional part is just for when user's are created.
  has_and_belongs_to_many :leagues, class_name: "Leagues::League", join_table: "users_leagues_leagues"
  has_one :customer, class_name: "Payments::Customer", dependent: :destroy
  has_many :unpaid_charges, class_name: "Payments::UnpaidCharge", dependent: :destroy
  has_many :charges, class_name: "Payments::Charge", dependent: :destroy
  has_many :cards, class_name: "Payments::Card", dependent: :destroy
  has_many :league_join_requests, class_name: "Leagues::JoinRequest", dependent: :destroy
  has_many :notifications, class_name: "Notification", foreign_key: :recipient_id
  has_many :league_invitations, class_name: "Leagues::Invitation", dependent: :destroy
  has_many :teams, class_name: "Leagues::Team"
  has_many :divisions, class_name: "Leagues::Division" # Can act as division commissioner
  has_many :conferences, class_name: "Leagues::Conference" # Can act as conference commissioner

Модель лиги:

class Leagues::League < ApplicationRecord
  enum pay_level: [ :basic, :custom, :premium ]
  include PgSearch

  #################### Associations
  has_and_belongs_to_many :users, class_name: "User", join_table: "users_leagues_leagues"
  has_and_belongs_to_many :commissioners, class_name: "User", join_table: "commissioners_leagues_leagues"
  belongs_to :commissioner, class_name: "User", foreign_key: :commissioner_id, optional: true
  has_and_belongs_to_many :feature_requests, class_name: "FeatureRequest", join_table: "feature_requests_leagues_leagues"
  has_many :join_requests, class_name: "Leagues::JoinRequest", dependent: :destroy
  has_many :invitations, class_name: "Leagues::Invitation", dependent: :destroy
  has_many :notifications, class_name: "Notification", as: :notifiable_subject, dependent: :destroy
  has_many :teams, class_name: "Leagues::Team", dependent: :destroy
  has_many :conferences, class_name: "Leagues::Conference", dependent: :destroy
  has_many :divisions, class_name: "Leagues::Division", dependent: :destroy

person Nathan Lauer    schedule 08.06.2018    source источник
comment
Можете ли вы предоставить больше информации о моделях, которые вы хотите использовать для сериализации и полиморфных ассоциациях?   -  person Wasif Hossain    schedule 10.06.2018
comment
Готово - добавил информацию о каждой из моделей. Полиморфная ассоциация происходит от гема pg_search (который выполняет полнотекстовый поиск в наборе таблиц базы данных postgres), что означает, что каждый элемент в возвращаемом списке найденных объектов доступен через полиморфную переменную с именем searchable   -  person Nathan Lauer    schedule 11.06.2018


Ответы (1)


Если вы хотите определить конкретный поиск сериализатора для своих ассоциаций, вы можете переопределить метод ActiveModel::Serializer.serializer_for, чтобы он возвращал класс сериализатора на основе определенных условий.

В вашем случае это может выглядеть примерно так:

class SearchBarSerializer < ApplicationSerializer
  attributes :searchable_type
  belongs_to :searchable

  class << self
    def serializer_for(model, options)
      return TinyUserSerializer if model.class == User
      return TinyLeagueSerializer if model.class == Leagues::League

      super
    end
  end
end
person Wasif Hossain    schedule 11.06.2018
comment
Эй, @Nathan, это сработало? если да, можете ли вы пометить это как ответ, чтобы другие тоже могли его принять. Спасибо. - person Wasif Hossain; 13.06.2018
comment
заметил, что я также ответил на один из ваших прошлых вопросов - seri" title="rails activemodelserializer объединяет два списка моделей одного типа в один seri">stackoverflow.com/questions/48104901/. Надеюсь, вы так же заботитесь о времени разработчиков, как и о своем. спасибо - person Wasif Hossain; 13.06.2018
comment
Извините, я был в процессе переезда и только что вернулся и увидел это! Сработало, искренне благодарю! - person Nathan Lauer; 13.06.2018
comment
мы ценим Ваш отзыв! - person Wasif Hossain; 14.06.2018