【发布时间】:2018-08-27 15:09:04
【问题描述】:
我有一个名为 Person 的模型和一个名为 Contract 的模型。 Person has_many Contracts,以及Contract belongs_to Person。
合同有一个start_date和一个end_date。如果当前日期介于两者之间,则合同被视为有效。
我在合同上有一个名为“active”的范围,它会相应地返回记录。一个人可以有任意数量的非活动合同,但应该只有一个活动合同。
我正在尝试找出添加验证以防止任何这些情况的最佳方法:
- 与已拥有有效合同的关联人员创建新的有效合同。
- 将现有活动合同中的关联人员更改为已拥有活动合同的人员。
- 当关联的 Person 已经有一个活动的合同时,将一个不活动的合同更改为具有使其活动的 start_date 或 end_date。
- 创建一个关联多个活动合同的人员。
这就是我目前正在做的事情,它似乎有效:
class Contract < ApplicationRecord
belongs_to :person
validates_uniqueness_of :person_id, conditions: -> { active }
scope :active, -> { where("start_date <= ? AND end_date >= ?", Date.today, Date.today) }
end
对我来说,这感觉有点像 hack。我不关心独特性,我关心的是大小;它只是碰巧唯一性起作用。如果我想允许不超过 2 个有效合同怎么办?
此外,当我尝试添加多个活动合同时返回的验证错误显示“人员已被占用”,这具有误导性。当然,我可以添加自定义消息,但这似乎是我做错了的另一种迹象。
【问题讨论】:
-
将逻辑委托给 Person 怎么样?在 Person 上创建一个类似于“active_contract_count”的范围,当需要创建合约时,从 Person 的“create_contracts(contracts)”之类的方法中创建,该方法在尝试创建合约之前测试 active_contract_count,然后还查看每个合约和测试他们的.active?如果它们在指定的日期范围内,则返回。
-
@bkimble 也许,但是验证对现有合约的更新呢?尝试通过人员模型执行所有创建/更新合同操作似乎会变得混乱。它可能会防止出现不需要的情况,但如果我理解正确,你建议我不要使用内置的-在 Rails 验证功能中?在我看来,那时我最好使用 validates_with 和自定义验证器类。
标签: ruby-on-rails