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
- 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.
- Performance: Every unknown method call on the controller goes through a regex match before raising or delegating.
- Undebuggable: Stack traces through
method_missing are harder to read. IDEs cannot find usages of these methods.
- 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
Description
app/controllers/application_controller.rblines 11–29 usemethod_missingto intercept allcan_*?andcan_*!calls and delegate them tocurrent_user:This is used throughout every controller as the authorization mechanism.
Problems
can_edit_healt_checks!) silently fall through—no NoMethodError, no error, the check just passes or fails in unexpected ways.method_missingare harder to read. IDEs cannot find usages of these methods.respond_to_missing?is not implemented, breaking Ruby metaprogramming conventions.Suggested approach
Define explicit helper methods in a
Permissionsconcern, either generated dynamically on load or listed explicitly:Effort: medium