我有一个带有子lookups
模型的多态ContractType
表。我在before_save
模型中有一个ContractType
回调,它设置了一个category
,但它似乎没有用。
class Lookup < ActiveRecord::Base
validates :value, presence: true
validates :category, presence: true
end
class ContractType < Lookup
before_save { self.category = "contract_type" }
end
然后我打开rails c
:
> c = ContractType.create(value: "test")
> c.errors.messages
=> { :category => ["can't be blank"] }
我没有收到任何错误,只是验证失败。据我所知,语法看起来是正确的,只是before_save
回调似乎不起作用...
我在这里遗漏了明显的东西吗?
我发现了问题...验证是在save
之前进行的,因此它总是“失败”,并且在before_save
回调发生之前就停止了。
解决方案是使用before_validation
回调。
class ContractType < Lookup
before_validation { self.category = "contract_type" }
end
我对事件顺序的误解。
我知道您找到了解决方案,但请从逻辑上考虑问题和解决方案。您正在对类别值进行硬编码。这意味着用户不能将其留空。它将始终被填充。那么,为什么首先要对其进行验证?只需删除此:
validates :category, presence: true
在before_save回调中,您将知道将分配该值。 before_validation确实有用例。例如,用户输入货币属性的值,而您想要在验证之前格式化货币。但对于您而言,则不需要before_validation。