如何使用Rails验证对象数组中的每个对象?
我正在我们的Rails应用程序中构建用户配置文件表单.在用户模型内部,我们有基本的字符串属性,但也有一些jsonb字段. JSONb字段默认为[],因为我们希望在该属性中存储一个对象数组.以下是简化用户模型属性的示例:
>名称:字符串
>电子邮件:字符串
>教育:jsonb,默认:[]
教育是一系列对象,例如:
[{ school: 'Harvard university',degree: 'Computer Science',from_date: 'Tue,11 Jul 2017 16:22:12 +0200`,to_date: 'Tue,11 Jul 2017 16:22:12 +0200' },{ school: 'High school',degree: 'Whatever',11 Jul 2017 16:22:12 +0200' }]
用户应该能够单击添加学校按钮,通过jquery添加更多字段.那个jquery部分对于这个问题并不重要 – 可能只是解释了为什么我们使用了一个对象数组.
你如何验证教育数组中的每个项目,所以我可以用红色标记包含验证错误的文本字段?我被告知使用FormObject模式可能会有所帮助.我也尝试编写继承自ActiveModel :: Validator类的自定义验证器,但主要问题仍然在于,我正在处理数组,而不是实际对象.
感谢任何建设性的帮助.
解决方法
您可以通过为它们引入非数据库支持的ActiveModel模型类,将教育记录视为Rails模型层中的一等公民:
class Education include ActiveModel::Model attr_accessor :school,:degree,:from_date,:to_date validates :school,presence: true validates :degree,presence: true def initialize(**attrs) attrs.each do |attr,value| send("#{attr}=",value) end end def attributes [:school,:to_date].inject({}) do |hash,attr| hash[attr] = send(attr) hash end end class ArraySerializer class << self def load(arr) arr.map do |item| Education.new(item) end end def dump(arr) arr.map(&:attributes) end end end end
然后,您可以在User模型中透明地序列化和反序列化教育数组:
class User # ... serialize :education,Education::ArraySerializer # ... end