Skip to content

Instantly share code, notes, and snippets.

@chrisbloom7
Last active August 6, 2025 18:53
Show Gist options
  • Select an option

  • Save chrisbloom7/e7e67410f47574e102a7942dfba2a8ef to your computer and use it in GitHub Desktop.

Select an option

Save chrisbloom7/e7e67410f47574e102a7942dfba2a8ef to your computer and use it in GitHub Desktop.

Revisions

  1. chrisbloom7 revised this gist Aug 6, 2025. 1 changed file with 8 additions and 8 deletions.
    16 changes: 8 additions & 8 deletions abilities_debug.rb
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,3 @@
    user = User.find(...)
    action = :some_action
    subject = SomeThing
    ability = Ability.new(user, ...)

    audit_ability(ability:, action:, subject:)

    def audit_ability(ability:, action:, subject:)
    begin
    ability.authorize!(action, subject)
    @@ -25,4 +18,11 @@ def audit_ability(ability:, action:, subject:)
    puts "CanCanCan::AccessDenied: User does not have ability to #{exception.action} for #{exception.subject.inspect} for indeterminate reasons"
    end
    end
    end
    end

    user = User.find(...)
    action = :some_action
    subject = SomeThing
    ability = Ability.new(user, ...)

    audit_ability(ability:, action:, subject:)
  2. chrisbloom7 revised this gist Aug 6, 2025. 1 changed file with 24 additions and 19 deletions.
    43 changes: 24 additions & 19 deletions abilities_debug.rb
    Original file line number Diff line number Diff line change
    @@ -1,23 +1,28 @@
    user = User.find(...)
    action = :some_action
    subject = SomeThing.new(...)
    subject = SomeThing
    ability = Ability.new(user, ...)

    begin
    ability.authorize!(action, subject)
    rescue CanCan::AccessDenied => exception
    matching_rules = ability.send(:relevant_rules_for_match, exception.action, exception.subject)
    failed_rules = matching_rules.reject do |rule|
    rule.matches_conditions?(exception.action, exception.subject)
    end

    if matching_rules.any? && failed_rules.any?
    describe_rules = failed_rules.map { |rule| { conditions: rule.conditions, block: rule.instance_variable_get(:@block) } }
    audit_ability(ability:, action:, subject:)

    def audit_ability(ability:, action:, subject:)
    begin
    ability.authorize!(action, subject)
    puts "CanCanCan: User has ability to #{action} for #{subject.inspect}"
    rescue CanCanCan::AccessDenied => exception
    failed_rules = ability.send(:relevant_rules_for_match, exception.action, exception.subject).reject do |rule|
    rule.matches_conditions?(exception.action, exception.subject)
    end

    puts "CanCanCan::AccessDenied: User has ability to #{exception.action} for\n"
    pp exception.subject
    puts "\nbut failed to satisfy conditions:\n\n- " \
    "#{describe_rules.join("\n- ")}"
    else
    puts "CanCanCan::AccessDenied: User does not have ability to #{exception.action} " \
    "#{exception.subject.inspect}"
    if failed_rules.any?
    puts "CanCanCan::AccessDenied: User does not have ability to #{exception.action} for #{exception.subject.inspect} due to the following conditions:\n"

    failed_rules.map do |rule|
    pp { conditions: rule.conditions, block: rule.instance_variable_get(:@block) }
    puts ""
    end
    else
    puts "CanCanCan::AccessDenied: User does not have ability to #{exception.action} for #{exception.subject.inspect} for indeterminate reasons"
    end
    end
    end
    end
  3. chrisbloom7 created this gist Aug 6, 2025.
    23 changes: 23 additions & 0 deletions abilities_debug.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,23 @@
    action = :some_action
    subject = SomeThing.new(...)

    begin
    ability.authorize!(action, subject)
    rescue CanCan::AccessDenied => exception
    matching_rules = ability.send(:relevant_rules_for_match, exception.action, exception.subject)
    failed_rules = matching_rules.reject do |rule|
    rule.matches_conditions?(exception.action, exception.subject)
    end

    if matching_rules.any? && failed_rules.any?
    describe_rules = failed_rules.map { |rule| { conditions: rule.conditions, block: rule.instance_variable_get(:@block) } }

    puts "CanCanCan::AccessDenied: User has ability to #{exception.action} for\n"
    pp exception.subject
    puts "\nbut failed to satisfy conditions:\n\n- " \
    "#{describe_rules.join("\n- ")}"
    else
    puts "CanCanCan::AccessDenied: User does not have ability to #{exception.action} " \
    "#{exception.subject.inspect}"
    end
    end