我有两个类属性的两个自定义验证方法。两者共享相同的代码,但属性不同。你能帮我减少这里的代码重复吗?
validates validation_fcn_for_attr_1
validates validation_fcn_for_attr_2
def validation_fcn_for_attr1:
.
<same body with attr1>
.
end
def validation_fcn_for_attr2:
.
<same body with attr2>
.
end
这是我的用例:
validate :verify_valid_locations
validate :verify_loactions_for_vacation
validate :another_validation_fcn
validates :travel_dist, number: {greater_than: 0}
def verify_valid_locations
acceptable_locations = ["C", "T", "G"]
unless locations.in? acceptable_locations
errors.add(:base, 'Acceptable towns for move are "C", "T", "G"')
end
end
def verify_loactions_for_vacation
acceptable_locations = ["C", "T", "G"]
unless vacation_locations.in? acceptable_locations
errors.add(:base, 'Acceptable towns for paid vacation are "C", "T", "G"')
end
end
编辑:现在您已经提供了真实的代码,我发现您实际上是在进行包含验证,您可以使用内置的 Rails 验证技术来完成此操作。方法如下:
validates :locations,
:vacation_locations,
inclusion: { in: ['C', 'T', 'G'],
message: 'Acceptable towns are "C", "T", "G"' }
请注意,错误不会添加到
base
属性中,它们将添加到实际属性中。这几乎总是更可取的。有几种方法可以实现这一点。如果您提供有关实际示例的更多详细信息,我可以提供更多帮助。但现在您可以为共享代码设置一个辅助方法并从两种验证方法中调用它:
# app/models/model_name.rb
validate :validation_fcn_for_attr_1
validate :validation_fcn_for_attr_2
def validation_fcn_for_attr1
helper(attr1)
end
def validation_fcn_for_attr2
helper(attr2)
end
def helper(attr)
.
<shared body>
.
end
private :helper
或者如果验证足够简单,您可能更喜欢:
# app/models/model_name.rb
validate :validation_fcn
def validation_fcn
[attr_1, attr_2].each do |attr|
.
<shared body>
.
end
end
private :validation_fcn
或者您可以使用
validates_each
块:
validates_each :attr_1, :attr_2 do |record, attr, value|
.
<shared body>
.
end
或者您可以创建一个完整的正确自定义验证器并在两个属性上调用它。如果您想走那条路,请告诉我,我可以提供帮助。 (如果您发布更接近您的实际验证技术和/或属性名称的内容可能会更容易。) 最终看起来像这样:
# app/models/model_name.rb
validates :attr_1,
:attr_2,
custom_validator_name: true
# app/validators/custom_validator_name.rb
class CustomValidatorName < ActiveModel::EachValidator
def validate_each(record, attribute, value)
.
<validation code>
.
end
end