Rails:验证一个字段只有在另一个字段存在时才存在

时间:2021-08-09 11:51:44

I have a model where there are two fields that can technically be null. The field names are :is_activated and :activated_at. :activated_at is only required if :is_activated is set to true. It does not need to be present if :is_activated is false. What's the appropriate way in Rails to set this validation directly into ActiveRecord?

我有一个模型,其中有两个字段在技术上可以是空的。字段名是:is_activated和:activated_at。:activated_at只需要if: is_active设置为true。如果:is_是假的,它不需要存在。在Rails中,将这种验证直接设置为ActiveRecord的合适方法是什么?

4 个解决方案

#1


31  

You can use a Proc on the :activated_at validator.

您可以在:activated_at验证器上使用Proc。

validates :activated_at, :presence, if: Proc.new { |a| a.is_activated? }

Recommended Reading:

推荐阅读:


Finally, you should consider renaming :is_activated to simply :activated. This is considered better practice in Rails. The is_ prefix is used in other languages for boolean attributes because their method names don't support a ? character. Ruby does, and Rails generates ___? methods on boolean attributes. Because of this it's better to just call the attribute :activated and check it with activated?.

最后,您应该考虑重命名:is_activationto:激活。这在Rails中被认为是更好的实践。is_前缀在其他语言中用于布尔属性,因为它们的方法名不支持a ?的性格。Ruby有,Rails生成___?布尔属性的方法。因此,最好只调用属性:activate并检查它是否被激活。

#2


2  

Non-Boolean Attributes.

If you're not using a Boolean attribute, like is_activated, and want to ensure that one attribute is present when another, non-Boolean attribute is present, you can simplify it:

如果您不使用布尔属性(如is_activated),并且希望在出现另一个非布尔属性时确保出现一个属性,则可以简化它:

validates :activated_at, presence: true, if: :activated_by?

activated_by? will return false when null and true otherwise.

activated_by吗?将返回false,否则返回null和true。

#3


1  

You could do something like this:

你可以这样做:

validates :activated_at, presence: true, if: :is_activated?

def is_activated?
  self.is_activated
end

This will only validate :activated_at if the method is_activated? returns true.

只有当方法is_激活时,才会验证:activated_at ?返回true。

#4


0  

You can also use a string with Ruby code that will be evaluated using eval:

您还可以使用带有Ruby代码的字符串,使用eval对其进行评估:

validates :activated_at, presence: true, if: 'is_activated'

I think it is an elegant solution when having such a short condition, although this option has been removed in Rails 5.2.

虽然在Rails 5.2中已经删除了这个选项,但我认为,在出现如此短的条件时,这是一种优雅的解决方案。

#1


31  

You can use a Proc on the :activated_at validator.

您可以在:activated_at验证器上使用Proc。

validates :activated_at, :presence, if: Proc.new { |a| a.is_activated? }

Recommended Reading:

推荐阅读:


Finally, you should consider renaming :is_activated to simply :activated. This is considered better practice in Rails. The is_ prefix is used in other languages for boolean attributes because their method names don't support a ? character. Ruby does, and Rails generates ___? methods on boolean attributes. Because of this it's better to just call the attribute :activated and check it with activated?.

最后,您应该考虑重命名:is_activationto:激活。这在Rails中被认为是更好的实践。is_前缀在其他语言中用于布尔属性,因为它们的方法名不支持a ?的性格。Ruby有,Rails生成___?布尔属性的方法。因此,最好只调用属性:activate并检查它是否被激活。

#2


2  

Non-Boolean Attributes.

If you're not using a Boolean attribute, like is_activated, and want to ensure that one attribute is present when another, non-Boolean attribute is present, you can simplify it:

如果您不使用布尔属性(如is_activated),并且希望在出现另一个非布尔属性时确保出现一个属性,则可以简化它:

validates :activated_at, presence: true, if: :activated_by?

activated_by? will return false when null and true otherwise.

activated_by吗?将返回false,否则返回null和true。

#3


1  

You could do something like this:

你可以这样做:

validates :activated_at, presence: true, if: :is_activated?

def is_activated?
  self.is_activated
end

This will only validate :activated_at if the method is_activated? returns true.

只有当方法is_激活时,才会验证:activated_at ?返回true。

#4


0  

You can also use a string with Ruby code that will be evaluated using eval:

您还可以使用带有Ruby代码的字符串,使用eval对其进行评估:

validates :activated_at, presence: true, if: 'is_activated'

I think it is an elegant solution when having such a short condition, although this option has been removed in Rails 5.2.

虽然在Rails 5.2中已经删除了这个选项,但我认为,在出现如此短的条件时,这是一种优雅的解决方案。