Предотвращение случайной сериализации моделей ActiveRecord

Мы внедрили патч для предотвращения случайной сериализации моделей ActiveRecord без указания полей для сериализации. Это изменение гарантирует, что мы контролируем, какие поля включаются, избегая потенциальных проблем с неполными или избыточными данными.

По умолчанию рендеринг модели ActiveRecord в формате JSON включает все атрибуты, что во многих случаях может быть нежелательно. Чтобы внедрить лучшие практики, необходимо указывать, какие поля должны быть сериализованы.

Примеры использования

Неправильное использование:

def show
  @user = User.first
  render json: @user
end

В среде разработки и при тестировании это приведет к следующей ошибке:

ActiveRecordSerializationSafety::BlockedSerializationError:
Сериализация моделей ActiveRecord (User) без указания полей не допускается.
Используйте сериализатор или передайте опцию :only в метод #serializable_hash. Подробнее: https://meta.discourse.org/t/-/314495
./lib/freedom_patches/active_record_disable_serialization.rb:15:in `serializable_hash'

Правильное использование:

  1. Использование сериализатора
class UserSerializer < ApplicationSerializer
  attributes :id, :email
end

def show
  @user = User.first
  render json: @user, serializer: UserSerializer
end
  1. Использование опции :only
def show
  @user = User.first
  render json: @user.as_json(only: [:id, :email])
end

Этот документ находится под контролем версий — предложите изменения на GitHub.

6 лайков

Для уточнения тем, кто может столкнуться с этим на практике: это означает, что любое использование методов сериализации в ActiveModel::Serialization, например as_json, независимо от контекста (включая тесты), приведёт к ошибке, если не передан параметр only. Подробнее:

Пример:

5 лайков

Пост был разделён на новую тему: Помощь с новыми защитами сериализации

Что ж, прошло 21 день, но я наконец разобрался в том, что вы написали здесь в связанном коде, по крайней мере в одном контексте, и надеюсь, что и в другом, упомянутом в разделе выше. Этот второй кажется сложнее (по крайней мере, по моей памяти), так как я не совсем понимаю, где именно проблема.

Спасибо, что спасли день (или хотя бы этот день). :beers:

Другая проблема заключалась в том, что моя модель server включала модель user, и мне нужно было вызывать сериализатор пользователя (или ограничивать поля) модели пользователя в сериализаторе сервера.

Оказалось, что мне вообще не нужна была модель пользователя в модели сервера (user_id уже был там, и есть вполне вероятная возможность, что даже это мне не нужно).

1 лайк