CanCanCommunity/cancancan · error · CanCan::NotImplemented

This model adapter does not support matching on a conditions

Error message

This model adapter does not support matching on a conditions hash.

What it means

AbstractAdapter#matches_conditions_hash? (lib/cancan/model_adapters/abstract_adapter.rb:35) is a template method that raises CanCan::NotImplemented. It is only reachable on a model adapter whose override_conditions_hash_matching? returns true but which never implemented matches_conditions_hash? — i.e., an incomplete custom adapter. It fires when a rule with a conditions hash is checked against an in-memory record (can?/authorize!).

Source

Thrown at lib/cancan/model_adapters/abstract_adapter.rb:35

      # Used to determine if the given adapter should be used for the passed in class.
      def self.for_class?(_member_class)
        false # override in subclass
      end

      # Override if you need custom find behavior
      def self.find(model_class, id)
        model_class.find(id)
      end

      # Used to determine if this model adapter will override the matching behavior for a hash of conditions.
      # If this returns true then matches_conditions_hash? will be called. See Rule#matches_conditions_hash
      def self.override_conditions_hash_matching?(_subject, _conditions)
        false
      end

      # Override if override_conditions_hash_matching? returns true
      def self.matches_conditions_hash?(_subject, _conditions)
        raise NotImplemented, 'This model adapter does not support matching on a conditions hash.'
      end

      # Override if parent condition could be under a different key in conditions
      def self.parent_condition_name(parent, _child)
        parent.class.name.downcase.to_sym
      end

      # Used above override_conditions_hash_matching to determine if this model adapter will override the
      # matching behavior for nested subject.
      # If this returns true then nested_subject_matches_conditions? will be called.
      def self.override_nested_subject_conditions_matching?(_parent, _child, _all_conditions)
        false
      end

      # Override if override_nested_subject_conditions_matching? returns true
      def self.nested_subject_matches_conditions?(_parent, _child, _all_conditions)
        raise NotImplemented, 'This model adapter does not support matching on a nested subject.'
      end

View on GitHub (pinned to 8c1bf153a3)

Solutions

  1. If you maintain the adapter: implement self.matches_conditions_hash?(subject, conditions) to evaluate the hash against the subject.
  2. Or return false from override_conditions_hash_matching? so CanCanCan falls back to its built-in hash matching.
  3. If you just use the gem: switch the model to a supported ORM (ActiveRecord) or update/patch the third-party adapter.
  4. Avoid hash conditions for that model until the adapter supports them (use blocks).

Example fix

# before (custom adapter)
class MyAdapter < CanCan::ModelAdapters::AbstractAdapter
  def self.override_conditions_hash_matching?(_subject, _conditions)
    true # promises hash matching...
  end
  # ...but matches_conditions_hash? is never implemented -> NotImplemented
end

# after
class MyAdapter < CanCan::ModelAdapters::AbstractAdapter
  def self.override_conditions_hash_matching?(_subject, _conditions)
    false # let CanCanCan's default hash matching handle it
  end
  # or implement it:
  # def self.matches_conditions_hash?(subject, conditions)
  #   conditions.all? { |k, v| subject.public_send(k) == v }
  # end
end
Defensive patterns

Strategy: validation

Validate before calling

# adapter authors: only claim the override you implement
class MyAdapter < CanCan::ModelAdapters::AbstractAdapter
  def self.override_conditions_hash_matching?(_subject, _conditions)
    respond_to?(:matches_conditions_hash?) && !method(:matches_conditions_hash?).owner == MyAdapter rescue false
  end
end
# users of a broken adapter: avoid hash conditions for that model
can :read, Widget { |w| w.visible? } # block conditions skip the hash-matching path

Type guard

def adapter_supports_hash_matching?(adapter)
  !adapter.override_conditions_hash_matching?(nil, {}) || adapter.method(:matches_conditions_hash?).owner != CanCan::ModelAdapters::AbstractAdapter
end

Try / catch

begin
  can?(:read, widget)
rescue CanCan::NotImplemented => e
  Rails.logger.error("adapter incomplete: #{e.message}")
  false
end

Prevention

When it happens

Trigger: Writing a custom adapter for Sequel/DataMapper/etc. that declares def self.override_conditions_hash_matching?(_, _); true; end without implementing matches_conditions_hash?, then calling can?(:read, record) with hash conditions for that model; a third-party adapter gem whose version lags the CanCanCan API.

Common situations: Bringing CanCanCan to a non-ActiveRecord ORM by copying the ActiveRecord adapter skeleton; upgrading cancancan so the adapter contract gained new methods your fork predates.

Related errors


AI-assisted analysis of CanCanCommunity/cancancan@8c1bf153a3 (2026-08-21). Data as JSON: /api/errors/aaa5cf70c7e18736. Report an issue: GitHub.