diff --git a/lib/cancan/conditions_matcher.rb b/lib/cancan/conditions_matcher.rb index c1a97b96..8120a00a 100644 --- a/lib/cancan/conditions_matcher.rb +++ b/lib/cancan/conditions_matcher.rb @@ -88,6 +88,9 @@ def matches_hash_conditions?(adapter, subject, conditions) end def condition_match?(attribute, value) + if defined?(ActiveRecord) && value.is_a?(ActiveRecord::Relation) + value = value.map { |v| v.attributes.compact_blank.values[0] } + end case value when Hash hash_condition_match?(attribute, value) diff --git a/spec/cancan/model_adapters/active_record_adapter_spec.rb b/spec/cancan/model_adapters/active_record_adapter_spec.rb index 810af592..6ca40f8d 100644 --- a/spec/cancan/model_adapters/active_record_adapter_spec.rb +++ b/spec/cancan/model_adapters/active_record_adapter_spec.rb @@ -276,6 +276,19 @@ class User < ActiveRecord::Base expect(Article.accessible_by(@ability)).to match_array([article1]) end + it 'matches records for can? when a condition value is an ActiveRecord relation selecting ids' do + user = User.create!(name: 'Arthur Dent') + article = Article.create!(name: 'How to fly', user: user) + other_article = Article.create!(name: 'Mostly Harmless') + ability = Ability.new(user) + + ability.can :read, Article, id: Article.where(user_id: user.id).select(:id) + + expect(Article.accessible_by(ability)).to match_array([article]) + expect(ability.can?(:read, article)).to eq(true) + expect(ability.can?(:read, other_article)).to eq(false) + end + it 'fetches only associated records when using with a scope for conditions' do @ability.can :read, Article, Article.where(secret: true) category1 = Category.create!(visible: false)