Проверки сериализованных данных Rails - PullRequest
5 голосов
/ 04 октября 2010

У меня есть поле, которое сериализовано в YAML через поведение AR по умолчанию.В настоящее время он находится в массиве хэшей для примеров:

[{'name' => 'hi', 'url' => 'bye'}, 
 {'name' => 'hi', 'url' => 'bye'}, 
 {'name' => 'hi', 'url' => 'bye'}]

Можно ли использовать некоторые базовые проверки AR для некоторых из этих полей?

Ответы [ 3 ]

16 голосов
/ 04 октября 2010

Да, используйте метод validates_each

serialize :urls
validates_each :urls do |record, attr, value|
  # value is an array of hashes
  # eg [{'name' => 'hi', 'url' => 'bye'}, ...]

  problems = ''
  if value
    value.each{|name_url| 
      problems << "Name #{name_url['name']} is missing its url. " \
        unless name_url['url']}
  else
    problems = 'Please supply at least one name and url'
  end
  record.errors.add(:urls, problems) unless problems.empty?
end

Добавлено: Вы не можете использовать проверки, такие как validates_length_of, так как метод проверки не понимает формат вашего сериализованного поля.

Метод validates_each хорош, поскольку он позволяет вам написать свой собственный метод проверки. Затем метод может добавить ошибку к записи, если это необходимо.

Совет: Вы также можете добавить ошибку к :base record.errors, а не к определенному атрибуту. Иногда это может помочь с форматированием сообщений об ошибках в ваших представлениях.

1 голос
/ 05 января 2015

Оставьте это здесь на случай, если это поможет кому-нибудь в будущем - я написал гем, чтобы лучше обрабатывать проверку сериализованных атрибутов Вы можете просто поместить эти проверки в синтаксис блока, способами, которые вы можете ожидать:

serialize :urls
validates_hash_keys :urls do
  validates :name, presence: true
  validates :url, presence: true
end

https://github.com/brycesenz/validates_serialized

0 голосов
/ 08 марта 2019

В модели

store :field_name, :name
store :field_name, :url

validates :name, presence: true
validates :url, presence: true

Он также предоставит вам атрибуты доступа, так что вы можете использовать их как обычные поля как:

object.name = 'some value' # reader
object.name # writer
object.url = 'some url' # reader
object.url # writer
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...