Rails序列化数据验证

时间:2010-10-04 16:31:10

标签: ruby-on-rails serialization

我有一个通过默认AR行为序列化为YAML的字段。它目前在一个哈希数组中,例如:

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

有没有办法可以在其中某些字段上使用一些基本的AR验证?

3 个答案:

答案 0 :(得分:16)

是的,使用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方法很好,因为它可以让您编写自己的验证方法。然后,该方法可以在适当的时候向记录添加错误。

提示:您还可以向record.errors的:base添加错误,而不是向特定属性添加错误。有时这可以帮助您在视图中格式化错误消息。

答案 1 :(得分:1)

将此放在这里以防将来帮助任何人 - 我已经编写了一个宝石来更好地处理验证序列化属性。您可以按照以下方式将这些验证放在块语法中:

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

https://github.com/brycesenz/validates_serialized

答案 2 :(得分:0)

在模型中

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