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.'
endView on GitHub (pinned to 8c1bf153a3)
Solutions
- If you maintain the adapter: implement self.matches_conditions_hash?(subject, conditions) to evaluate the hash against the subject.
- Or return false from override_conditions_hash_matching? so CanCanCan falls back to its built-in hash matching.
- If you just use the gem: switch the model to a supported ORM (ActiveRecord) or update/patch the third-party adapter.
- 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 writing a custom adapter, flip each override_* flag to true only after the matching method is implemented.
- Copy the full ActiveRecord adapter as the skeleton rather than the abstract one, so no method is missing.
- Smoke-test the adapter with can?, authorize!, and accessible_by in its own spec suite before shipping.
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
- This model adapter does not support matching on a nested sub
- This model adapter does not support matching on a specific c
- This model adapter does not support fetching records from th
- You are not authorized to access this page.
- You can't specify target (#{target}) as alias because it is
AI-assisted analysis of CanCanCommunity/cancancan@8c1bf153a3 (2026-08-21).
Data as JSON: /api/errors/aaa5cf70c7e18736.
Report an issue: GitHub.