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:
推荐阅读:
- http://guides.rubyonrails.org/active_record_validations.html#using-a-proc-with-if-and-unless
- http://guides.rubyonrails.org/active_record_validations.html using-a-proc-with-if-and-unless
- http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html
- http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html
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:
推荐阅读:
- http://guides.rubyonrails.org/active_record_validations.html#using-a-proc-with-if-and-unless
- http://guides.rubyonrails.org/active_record_validations.html using-a-proc-with-if-and-unless
- http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html
- http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html
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中已经删除了这个选项,但我认为,在出现如此短的条件时,这是一种优雅的解决方案。