验证嵌套模型?
更具体地说,“如何验证模型需要至少创建 x 个有效的关联模型?”。 我一直在尝试验证以与父级相同的形式创建的嵌套模型(并最终像 jQuery 一样显示立即验证)。 作为一个流行的示例,我们假设以下模型和架构。
class Project
include DataMapper::Resource
property :id, Serial
property :title, String, :nullable => false
has 2..n, :tasks
end
class Task
include DataMapper::Resource
property :id, Serial
property :project_id, Integer, :key => true
property :title, String, :nullable => false
belongs_to :project
end
正如您所看到的,所有验证都是在架构定义中完成的。 这里重要的是“has 2..n, :tasks
”。 鉴于 params 哈希中的嵌套任务属性将生成有效任务,此验证实际上可以正常工作。 但是,如果它们生成无效任务,则该任务将不会被创建,并且您最终会得到一个任务少于 2 个的项目,因此是一个无效 > 项目对象。
据我了解,这是因为它无法确定任务属性是否有效,直到它尝试保存任务,并且因为 - 据我所知 - 任务可以'在项目之前保存,项目不知道任务是否有效。 我的假设正确吗?
不管怎样,我希望能有一个快速的答案,但这似乎比我希望的要简单得多。 如果您有任何建议,我们将不胜感激。
To be more specific, "How do I validate that a model requires at least x valid associated models to be created?". I've been trying to validate nested models that get created in the same form as the parent (and ultimately show immediate validations a la jQuery). As a popular example, lets assume the following models and schema.
class Project
include DataMapper::Resource
property :id, Serial
property :title, String, :nullable => false
has 2..n, :tasks
end
class Task
include DataMapper::Resource
property :id, Serial
property :project_id, Integer, :key => true
property :title, String, :nullable => false
belongs_to :project
end
All the validations are done in the schema definitions, as you can see. The important one here is "has 2..n, :tasks
". This validation actually works normally, given that the nested task attributes in the params hash will produce valid tasks. If they produce an invalid task, however, then the task won't get created and you'll end up with a Project that has less than 2 tasks, and thus an invalid project object.
As I understand it, this is because it can't figure out if the task attributes are valid or not until it attempts to save the tasks, and since - as far as I know - the tasks can't get saved before the project, the project is unaware if the tasks will be valid or not. Am I correct in assuming this?
Anyway, I was hoping there would be a quick answer, but it seems a lot less trivial then I'd hoped. If you've got any suggestions at all, that would be greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
实际上,我在这里使用 DataMapper 中的事务找到了一个很好的解决方案。 基本上,此事务尝试保存父对象以及所有子对象。 一旦保存失败,事务就会停止并且不会创建任何内容。 如果一切顺利,那么对象将成功保存。
这确保了在保存任何内容之前一切都是有效的。 我只需要在控制器代码中将 #save 和 #update 方法更改为 #make 即可。
I actually found a nice solution here using transactions in DataMapper. Basically this transaction tries to save the parent object as well as all the child objects. As soon as one fails to save, then the transaction stops and nothing gets created. If all goes well, then the objects will save successfully.
This assures that everything is valid before it anything gets saved. I just needed to change my #save and #update methods to #make in my controller code.
如果您的数据库引擎支持,SET CONSTRAINTS DEFERRED 可能会很有用。
否则,可能会编写一个存储过程来执行插入,然后说存储过程的职责是确保仅插入正确的、经过验证的数据。
SET CONSTRAINTS DEFERRED might be useful if your database engine supports that.
Otherwise, maybe write a stored procedure to do the inserts, and then say that its the resonsibility of the stored procedure to ensure that only correct, validated data is inserted.
有一个模型方法
valid?
可以在保存模型对象之前对其运行验证。 因此,验证关联的简单方法是使用 validates_with_block' 或 validates_with_method 来检查关联的验证。它看起来像这样
或者您可以查看 dm-association-validator 或 dm-accepts-nested-attributes
编辑: 更加疯狂。 对任务运行验证,然后检查唯一的错误是否与关联相关。
There is a model method
valid?
that runs the validations on a model object before it is saved. So, the simple way to validate the associations would be to usevalidates_with_block' or 'validates_with_method
to check the validations on the associations.It would look something like this
Or you could look at dm-association-validator or dm-accepts-nested-attributes
Edit: for extra crazy. run validations on the tasks, then check to see if the only errors are ones related to the association.