如何根据Rails中的其他对象验证多对多关联? [英] How to validate many-to-many association based on other object in Rails?

查看:28
本文介绍了如何根据Rails中的其他对象验证多对多关联?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:这是为简化而基于更复杂的实现创建的示例。

考虑一个用于提交租客详细信息的表单,以及一个用于添加公寓详细信息的子表单。仅当承租人声称年龄大于或等于18岁时,才应创建公寓记录。

基于承租人的1对1公寓验证

在以前的迭代中,这种关系是1对1,ID存储在对象上。我能够根据承租人信息验证公寓详细信息,如下所示:

class Apartment < ApplicationRecord
  validates :apartment_name, presence: true, if: lambda { |apartment|
    apartment.renter.try(:age) >= 18
  }

这种联系是直截了当的。但是,对于第三个连接表,可能不再有链接。

基于承租人的N对N公寓验证

尝试在lambda中使用apartment.renters会返回一个空的CollectionProxy,我想这与预期不谋而合,因为公寓记录尚未创建,并且无法添加到租赁表中。

请注意,如果承租人(17岁以下)通过验证,则应创建/更新承租人记录,而不应创建公寓记录(不应通过验证)。应如何根据承租人对象对公寓进行验证或设置条件?应在控制器或承租人模型中执行此操作?

示例模型

class Apartment < ApplicationRecord
  has_many :rentals
  has_many :renters, through: :rentals
  accepts_nested_attributes_for :renters, allow_destroy: true
end

class Renter < ApplicationRecord
  has_many :rentals
  has_many :apartments, through: rentals
  accepts_nested_attributes_for :apartments, allow_destroy: true
end

class Rental < ApplicationRecord
  belongs_to :apartment
  belongs_to :renter
end

推荐答案

目前,我已经解决了通过WebForm自然地处理验证错误的问题,验证发生在承租人对象上。这不是对所问问题的真正解决方案,因为它推迟了创建承租人而不是应用程序的条件--这对我不公平。

这是一个简单、典型的验证(没有什么新意),它阻止创建这两个记录:

class Renter < ApplicationRecord
  has_many :rentals
  has_many :apartments, through: rentals
  accepts_nested_attributes_for :apartments, allow_destroy: true

  validates_each :apartments do |record, attr, value|
    record.errors.add(attr, 'must be at least 18') if record.age < 18
  end
end

我不会问这个问题,如果我愿意接受这个解决方案或删除前面提到的条件。如果有人填写地址,我会选择更好的答案。

这篇关于如何根据Rails中的其他对象验证多对多关联?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆