ActiveModel :: Serializer и наследование: невозможно переопределить метод атрибутов - PullRequest
0 голосов
/ 05 ноября 2019

Я использую rails 5.2.3 для моего приложения API только для rails с active_model_serializer 0.10.10.

Мой код:

У меня есть BaseSerializer и UserSerializer. UserSerializer наследует BaseSerializer.

class Api::V1::BaseSerializer < ActiveModel::Serializer

  ActiveModelSerializers.config.key_transform = :camel_lower

  def attributes(*args)
    object.attributes.symbolize_keys
  end

end
class Api::V1::UserSerializer < Api::V1::BaseSerializer

  attributes :id, :name, :created_at

end

Почему эта реализация?

Мне действительно нужны мои UserSerializer (и мои сериализаторы будущего) для наследования от BaseSerializerтак что у меня есть все мои рендеры в camelCase.
И я хочу общий attributes метод в моем BaseSerializer, потому что мне не нужно объявлять сериализатор для каждой модели, которую я буду рендерить. По умолчанию я хочу, чтобы все поля отображались.

Благодаря ActiveModelSerializer, правильный сериализатор вызывается, когда я render json: ... в моих контроллерах.

То, что я исключил:

  • Когда мой API отображает другой объект, кроме User, например Article: не определено ArticleSerializer, поэтому используется BaseSerializer, и все атрибуты возвращаются -> это работаеткак я и предполагал ! :)
  • Когда мой API отображает объект User: используется UserSerializer (который наследуется от BaseSerializer). Но метод attributes в UserSerializer переопределяет метод в BaseSerializer, поэтому должны отображаться только поля name, id и created_at -> он не работает: все поля отображаются:(
    Я поставил byebug, и мы передаем метод attributes в BaseController.

Кроме того, чтобы доказать, что ActiveModelSerializer может найти мой UserSerializer: если мой UserSerializerнаследует ActiveModel::Seializer, а не BaseSerializer, только поля :id, :name и :created_at визуализируются (но их нет в camelCase, конечно).

Мне нужна ваша помощь, чтобыПонимаю, почему не работает переопределение. Пытаюсь ли я сделать что-то, что невозможно?

Спасибо и хорошего дня :)

Обновление

Я понял, что яперепутаны оба метода attributes. Там не то же самое (метод класса против метода экземпляра).

Я нашел способ сделать именно то, что я хочу:

class Api::V1::BaseSerializer < ActiveModel::Serializer

  ActiveModelSerializers.config.key_transform = :camel_lower

  def attributes(*_args)
    if self.class._attributes_data.empty?
      object.attributes.symbolize_keys
    else
      super
    end
  end

end

Все еще нужна помощь сообщества, чтобы узнать, еслиЯ все делаю правильно:)

Я не знаю, делаю ли я это самым простым или даже худшим способом, если это вообще не рекомендуется.

Спасибоеще раз.

...