def validate? (attr_validator, object = nil, hash = nil)
object ||= attr_validator.object
return false unless object
(hash || @conditions_hash).all? do |attr, value|
attr_value = object_attribute_value(object, attr)
if value.is_a?(Hash)
if attr_value.is_a?(Enumerable)
attr_value.any? do |inner_value|
validate?(attr_validator, inner_value, value)
end
elsif attr_value == nil
raise NilAttributeValueError, "Attribute #{attr.inspect} is nil in #{object.inspect}."
else
validate?(attr_validator, attr_value, value)
end
elsif value.is_a?(Array) and value.length == 2 and value.first.is_a?(Symbol)
evaluated = if value[1].is_a?(Proc)
attr_validator.evaluate(value[1])
else
value[1]
end
case value[0]
when :is
attr_value == evaluated
when :is_not
attr_value != evaluated
when :contains
begin
attr_value.include?(evaluated)
rescue NoMethodError => e
raise AuthorizationUsageError, "Operator contains requires a " +
"subclass of Enumerable as attribute value, got: #{attr_value.inspect} " +
"contains #{evaluated.inspect}: #{e}"
end
when :does_not_contain
begin
!attr_value.include?(evaluated)
rescue NoMethodError => e
raise AuthorizationUsageError, "Operator does_not_contain requires a " +
"subclass of Enumerable as attribute value, got: #{attr_value.inspect} " +
"does_not_contain #{evaluated.inspect}: #{e}"
end
when :intersects_with
begin
!(evaluated.to_set & attr_value.to_set).empty?
rescue NoMethodError => e
raise AuthorizationUsageError, "Operator intersects_with requires " +
"subclasses of Enumerable, got: #{attr_value.inspect} " +
"intersects_with #{evaluated.inspect}: #{e}"
end
when :is_in
begin
evaluated.include?(attr_value)
rescue NoMethodError => e
raise AuthorizationUsageError, "Operator is_in requires a " +
"subclass of Enumerable as value, got: #{attr_value.inspect} " +
"is_in #{evaluated.inspect}: #{e}"
end
when :is_not_in
begin
!evaluated.include?(attr_value)
rescue NoMethodError => e
raise AuthorizationUsageError, "Operator is_not_in requires a " +
"subclass of Enumerable as value, got: #{attr_value.inspect} " +
"is_not_in #{evaluated.inspect}: #{e}"
end
when :lt
attr_value && attr_value < evaluated
when :lte
attr_value && attr_value <= evaluated
when :gt
attr_value && attr_value > evaluated
when :gte
attr_value && attr_value >= evaluated
else
raise AuthorizationError, "Unknown operator #{value[0]}"
end
else
raise AuthorizationError, "Wrong conditions hash format"
end
end
end