I am trying to wrap my controller logic within the same conditional. Not sure how to achieve this as I am a bit new to ruby on rails. The pseudo code below is what I am trying to achieve
class Api::BaseController
include Api::AuthConcern if SAME_CONDITION
before_action -> { some_function() } if SAME_CONDITION
if SAME_CONDITION
rescue_from Api::AuthConcern::Unauthenticated do |e|
render status: 401, json: { error: e.error }
end
rescue_from Api::AuthConcern::PermissionDenied do |e|
render status: 403, json: { error: e.error }
end
end
end
CodePudding user response:
You ain't gonna need it. Just use methods instead:
module Api
# Avoid adding "Concern" to your module names
# it provides absolutely no information about what the object does
module AuthConcern
extend ActiveSupport::Concern
included do
rescue_from Unauthenticated { |e| respond_to_unauthenticated(e.error) }
rescue_from PermissionDenied { |e| respond_to_permission_denied(e.error) }
end
def respond_to_unauthenticated(message)
render status: 401, json: { error: message }
end
def respond_to_permission_denied(message)
render status: 403, json: { error: message }
end
end
end
This lets any class that includes the module customize the behavior by simply overriding the method:
module Api
class FooController < BaseController
# ...
private
def respond_to_unauthenticated(error)
render plain: 'Oh noes, you broke it!'
end
end
end
If you need to add more logic to to how a module augments the class with you can use the macro pattern. This is simply a class method that adds methods or behavior to the class:
module Api
module AuthConcern
extend ActiveSupport::Concern
# ....
module ClassMethods
def authenticate!(**kwargs)
before_action :authenticate!, **kwargs
end
end
end
end
module Api
class FooController < BaseController
authenticate! except: :index
end
end
This pattern is found all over Ruby in everything from attr_accessor
to Rails callbacks and assocations.