我有一个字段通过默认的AR行为序列化为YAML。它目前在一个哈希数组中作为例子:
[{'name' => 'hi', 'url' => 'bye'},
{'name' => 'hi', 'url' => 'bye'},
{'name' => 'hi', 'url' => 'bye'}]
有没有办法可以在其中一些领域使用一些基本的AR验证?
是的,使用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
添加错误,而不是添加到特定属性。有时这可以帮助您在视图中格式化错误消息。
离开这里,以防它将来帮助任何人 - 我写了一个宝石来更好地处理验证序列化属性。您可以将这些验证放在块语法中,这可能是您期望的方式:
serialize :urls
validates_hash_keys :urls do
validates :name, presence: true
validates :url, presence: true
end
在模型中
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