我有一个带有字段的模型,我在该字段中验证内容。我正在使用ActiveRecord验证来检查该内容的存在。但是,我希望能够保存,更新等,而无需检查有效性。我确实希望在特定时间获得有效性,并从中检索错误。
validates :my_content_in_field, presence: true, if: :should_validate
attr_accessor :should_validate
我想要传递
valid?
这将失败
valid?(should_validate: true)
验证失败后,我希望所有更新和保存按常规工作。这可能吗?我本质上想要利用ActiveRecords错误消息,但实际上并没有验证。
在星期五结束的一天结束时,我可能只是遗漏了一些明显的东西。
答案 0 :(得分:3)
I'm not sure you can call valid?(should_validate: true)
. valid?
method may be called with one parameter called context
(see docs). You should read a great post on validation contexts.
This should work:
class MyModel < ActiveRecord::Base
validates :something, on: :should_validate
...
end
m = MyModel.new
m.valid? # No validation happens
m.valid?(:should_validate) # Validates something
答案 1 :(得分:1)
I think the most efficient way is defining a specific method in your code like this:
class Model < ActiveRecord::Base
validates :my_content_in_field, presence: true, if: :should_validate
attr_accessor :should_validate
alias :super_valid? :valid?
# Define a custom loose validation method that
# will ignore :my_content_in_field
#
# As for the following method, the `context` param
# is needed to replicate the default signature
# of `ActiveRecord::Validations::valid?`
def loosely_valid?(context = nil)
@should_validate = false
super_valid? context
end
# Tweak the base valid? method
def valid?(context = nil)
@should_validate = true
super_valid? context
end
end
You will always validate the :my_content_in_field
parameter using the standard valid?
method unless when you call loosely_valid?
that will ignore that parameter forcing the @should_validate
attribute in your model.
This is achieved using a simple alias
call at the beginning of the method to override the standard valid?
method from ActiveRecord
.
This approach will always validate :my_content_in_field
when creating/updating the model. If you don't need this you can change the code changing those methods like this:
def strictly_valid?(context = nil)
@should_validate = true
super_valid? context
end
def valid?(context = nil)
@should_validate = false
super_valid? context
end
答案 2 :(得分:0)
The best I've been able to come up with is creating a custom method:
validates :my_content_in_field, presence: true, if: :should_validate
attr_reader :should_validate
def has_valid_data?
@should_validate = true
stored_valid = valid?
@should_validate = false
stored_valid
end
So now I get the desired behavior:
valid? #=> true
has_valid_data? #=> false
And I can collect my ActiveRecord error messages and be on my way. But I'd love to see a better way.
答案 3 :(得分:0)
If you're just trying to leverage ActiveRecord error messages and you never need valid?
to consider this field, a better approach would be to use the errors API directly:
def valid_data?
valid = valid?
errors.add(:my_field, 'invalid content') unless custom_field_is_valid? # your logic here
valid && errors.empty?
end
This will run the validation on all your other fields, adding their error messages, and then also add an error message for just this field.