Skip to content

Architecture: method_missing used for permission checks in ApplicationController—hides bugs and slows dispatch #42

@tkadauke

Description

@tkadauke

Description

app/controllers/application_controller.rb lines 11–29 use method_missing to intercept all can_*? and can_*! calls and delegate them to current_user:

def method_missing(method, *args)
  if method.to_s =~ /^can_.*\?$/
    ...
  elsif method.to_s =~ /^can_.*\!$/
    ...
  else
    super
  end
end

This is used throughout every controller as the authorization mechanism.

Problems

  1. Hidden bugs: Typos in permission method names (e.g., can_edit_healt_checks!) silently fall through—no NoMethodError, no error, the check just passes or fails in unexpected ways.
  2. Performance: Every unknown method call on the controller goes through a regex match before raising or delegating.
  3. Undebuggable: Stack traces through method_missing are harder to read. IDEs cannot find usages of these methods.
  4. No introspection: respond_to_missing? is not implemented, breaking Ruby metaprogramming conventions.

Suggested approach

Define explicit helper methods in a Permissions concern, either generated dynamically on load or listed explicitly:

module Permissions
  def can_edit_health_checks!(account, &block)
    current_user.can_edit_health_checks?(account) ? (block&.call) : deny_access
  end
end

Effort: medium

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions