Я использую 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
Все еще нужна помощь сообщества, чтобы узнать, еслиЯ все делаю правильно:)
Я не знаю, делаю ли я это самым простым или даже худшим способом, если это вообще не рекомендуется.
Спасибоеще раз.