Как выполнить код «before_serialize»? или Как я могу очистить атрибуты перед их сериализацией?

Я следую этому шаблону, чтобы гарантировать, что все мои атрибуты нормализованы перед сохранением:

class MyModel < ApplicationRecord
  before_validation :normalize_attributes

  def normalize_attributes
    self.name&.strip!
    self.email&.strip!
  end
end

У меня есть и другие, более сложные:

def normalize_attributes
  # Transform to array if it is a string with things
  # separated by comas
  if self.favorite_things.is_a? String
    self.favorite_things = self.favorite_things.split(",").map(&:strip)
  end
end

Это работает, но проблема в том, что когда я добавляю этот атрибут к serialized, он терпит неудачу:

serialize :favorite_things, Array

Как здесь:

my_model.update(favorite_things: "ONE, TWO, THREE")

Ошибка:

Error:
ActiveRecord::SerializationTypeMismatch: can't serialize `favorite_things`: was supposed to be a Array, but was a String. -- "ONE, TWO, THREE"

Похоже, что команда serialize выполняется раньше before_validation.

Как я могу очистить атрибуты перед их сериализацией?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Чтобы гарантировать, что все ваши атрибуты нормализованы перед сохранением, перезапишите установщики:

class MyModel < ApplicationRecord
  # @param value [String]
  # @return [String]
  def name=(value)
    super(value.strip)
  end
  
  # @param value [String]
  # @return [String]
  def email=(value)
    super(value.strip)
  end
  
  # @param value [String, Array]
  # @return [Array]
  def favorite_things=(value)
    return super(value) unless value.is_a? String
    
    super(favorite_things.split(",").map(&:strip))
  end
end

https://api.rubyonrails.org/classes/ActiveRecord/Base.html#class-ActiveRecord::Base-label-Overwriting+default+accessors

Да, это то, что я хотел сделать. Мне больше понравилась идея объединить все нормализации в одном методе. Но похоже, что это единственный вариант, который работает с serialize

fguillen 28.03.2024 04:22

Другие вопросы по теме