Rails AMS, укажите разные сериализаторы в полиморфном списке - PullRequest
0 голосов
/ 09 июня 2018

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

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

class SearchBarSerializer < ApplicationSerializer
  attributes :searchable_type
  belongs_to :searchable
end

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

Это нормально, но я бы хотел использовать разные сериализаторы для каждого типа.Это для панели поиска, и поэтому я забочусь только о гораздо меньшем количестве данных, чем полный стандартный сериализатор.(РЕДАКТИРОВАТЬ: стандартные сериализаторы сериализуют все атрибуты и ассоциации для каждой из моделей «Пользователь» и «Лига», что можно увидеть ниже. Каждая модель несколько значительно больше, и для целей поиска мне действительно нужно только название каждой модели и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

1 Ответ

0 голосов
/ 11 июня 2018

Если вы хотите определить конкретный поиск сериализатора для ваших ассоциаций, вы можете переопределить метод 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
...