Hi all, Congrats for the project!
Is there a way to validate filter values?
For example, I want to filter by name, but only if the name value is a string with more than 3 characters.
Is there a standard way to do this?
I couldn't find any documentation about this.
I haven't tried, but I assume you could just raise an error inside the filter callback. See http://jsonapi-resources.com/v0.9/guide/resources.html#Applying-Filters for how to implement a custom filter.
Thank you @scottgonzalez ! I have already looked at that doc.
What I was doing is something like:
filter :name, verify: ->(values, context) {
raise JSONAPI::Exceptions::InvalidFilterValue.new(:name, values) if ...
}
But I'm wondering if there is a standard way to validate the filter values, and return an error with all the "wrong" filters, something like:
{
"errors": [
{
"title": "Invalid filter value",
"detail": "[\"10\"] is not a valid value for name.",
"code": "107",
"status": "400"
},
{
"title": "Invalid filter value",
"detail": "[\"10\"] is not a valid value for last_name.",
"code": "107",
"status": "400"
}
]
}
BTW: It would be nice if we could something like:
filter :name, validate: { lenght: { min: 3, max: 20 } }
@edipox, JR does not support filters validators, but you can implement it yourself by overriding verify_filter.
something like code below can do the trick:
class JSONAPI::Validators::LengthValidator
def initialize(filter_name, values, options)
@filter_name = filter_name
@values = values
@options = options
end
def valid?
return false if !options[:allow_empty] && values.empty?
values.each do |value|
return false if options[:min] && value.length < options[:min]
return false if options[:max] && value.length > options[:max]
end
true
end
end
class ApplicationResource < JSONAPI::Resource
def self.verify_filter(filter, raw, context = nil)
result = super
options = _allowed_filters.fetch(filter, {})
options.fetch(:validate, {}).each do |validator, opts|
klass = "JSONAPI::Validators::#{validator.to_s.classify}Validator".constantize
unless klass.new(result[0], result[1], opts).valild?
raise JSONAPI::Exceptions::InvalidFilterValue.new(filter, raw)
end
end
result
end
end
class UserResource < ApplicationResource
attribute :name
filter :name, validate: { length: { min: 3, max: 20 } }
end
Thank you @senid231! That looks good. I'm just using verify for now. So I'll close this issue
Most helpful comment
@edipox,
JRdoes not support filters validators, but you can implement it yourself by overridingverify_filter.something like code below can do the trick: