module

CanCan

End-of-program codegen:

  • CanCan.model_* dispatchers: per-operation dispatch over the registered models. Each case branch calls on the LITERAL class — the static ActiveRecord::Base.class type does not know per-model methods generated by active_record_cr's codegen (same constraint devise_cr solves with typed procs), and unions/params collapse the metaclass.
  • cancan_action: action-string → Symbol dispatch for every registered controller (Crystal has no String#to_sym; actions are compile-time known). Runs alongside action_pack's own finished hook.

Constants

DEFAULT_ALIASES = {:read => [:index, :show], :create => [:new], :update => [:edit]} of Symbol => Array(Symbol)
REGISTERED_MODELS = [] of Nil

Compile-time model registry: {underscored resource name, class}.

Class methods

class_assoc_specs?(klass : ActiveRecord::Base.class) : Array(ActiveRecord::AssocSpec) | Nil
class_table_name(klass : ActiveRecord::Base.class) : String
class_table_name?(klass : ActiveRecord::Base.class) : String | Nil

nil-returning variants for the core Rule matcher (nested subjects work without registration via the class-name fallback). NOTE: if/elsif with == — case x; when SomeClass is an is_a? check on instances and never matches class objects.

conds_eq(a : CondVal, b : CondVal) : Bool
from_parameters_value(v) : ParamValue | Nil

ActionController::Parameters::Value → ParamValue.

hash_fragment(table : String, pk : String, specs : Array(ActiveRecord::AssocSpec), conds : Hash(String, CondVal)) : String | Nil

Hash conditions → AND-ed SQL. Nested hashes become (NOT) EXISTS subqueries through the association join (same result sets as the gem's LEFT JOIN aliasing).

inline(fragment : String, args : Array(DB::Any)) : String

Substitutes a fragment's ? placeholders with inlined literals.

lit(v) : String

SQL literal for a condition value (strings escaped by doubling quotes).

model_accessible_records(name : String, ability, action : Symbol) : Array(ActiveRecord::Base)
model_assign(name : String, record : ActiveRecord::Base, attrs : Hash(String, ActiveRecord::Value)) : Nil
model_assoc_specs(name : String) : Array(ActiveRecord::AssocSpec)
model_class(name : String) : Subject
model_find(name : String, id : Int64) : ActiveRecord::Base
model_new(name : String) : ActiveRecord::Base
model_table_name(name : String) : String
model_where_first(name : String, condition : String, value : String) : ActiveRecord::Base | Nil
name_for(klass : ActiveRecord::Base.class) : String | Nil
rule_fragment(model : ActiveRecord::Base.class, conditions : CondVal) : String | Nil

Renders one rule's conditions as a self-contained WHERE fragment (literals inlined, strings escaped). nil for blank conditions (matches everything).

to_cond(h : Hash) : Hash(String, CondVal)

Converts a user-written conditions literal (Hash(String, Bool) etc.) into Hash(String, CondVal) — Crystal generics are invariant.

to_cond_val(v) : CondVal
to_param_value(v) : ParamValue

Macros

register_model(klass)

Nested types