class MyAbility
include CanCan::Ability
def initialize
can %i[index show], Product, count_on_hand: [1..Float::INFINITY, nil]
end
end
ability = MyAbility.new
The user should have access to products that have count_on_hand set to nil or at least 1. This works when using accessible_by:
puts Product.accessible_by(ability).to_sql
# => SELECT `products`.* FROM `products` WHERE (`products`.`count_on_hand` IS NULL OR `products`.`count_on_hand` >= 1)
I digged into the source code and found out, that it simply uses a value.include?(attribute) when an Enumerable is used for a matcher
def condition_match?(attribute, value)
case value
when Hash
hash_condition_match?(attribute, value)
when Range
value.cover?(attribute)
when Enumerable
value.include?(attribute) # <---- her it asks [1..Float::INFINITY, nil].include?(1) which is false
else
attribute == value
end
end
It would be great, if the behaviour for hash conditions used for scopes and on a per object basis would be the same.
Unfortunately, I can't use
cannot %i[index show], Product, count_on_hand: 0
because this would exclude rows where count_on_hand is NULL
For now, I'm using a monkeypatch like this
def condition_match?(attribute, value)
case value
when Hash
hash_condition_match?(attribute, value)
when Range
value.cover?(attribute)
when Enumerable
value.any? { |v| condition_match?(attribute, v) }
else
attribute == value
end
end
But I'm unsure if this is a good / the right solution.
Hi, consider the following ability:
The user should have access to products that have
count_on_hand
set tonil
or at least1
. This works when usingaccessible_by
:However, when using it via
can?
it doesn't work:I digged into the source code and found out, that it simply uses a
value.include?(attribute)
when anEnumerable
is used for a matcherIt would be great, if the behaviour for hash conditions used for scopes and on a per object basis would be the same.
Unfortunately, I can't use
because this would exclude rows where
count_on_hand
isNULL
For now, I'm using a monkeypatch like this
But I'm unsure if this is a good / the right solution.