2
\$\begingroup\$

I have session controller for mobile devices. I would like to refactor it a little, for example because my session controller is sub class of Devise::SessionsController I had to duplicate error methods from BaseController.

class Api::V1::SessionsController < Devise::SessionsController
  include Devise::Controllers::Helpers
  prepend_before_filter :require_no_authentication, only: [:create]
  skip_load_and_authorize_resource
  before_filter :ensure_params_exist, only: [:create]

  respond_to :json

  def create
    if user_find params[:user][:member_id]
      self.resource = warden.authenticate!(auth_options)
      sign_in(resource_name, resource)
      resource.reset_authentication_token!
      resource.save!
    else
      error :not_found
    end
  end

  def destroy
    sign_out(resource_name)
  end

  private

  def user_find(id)
    User.find_by member_id: id
  end

  def ensure_params_exist
    unless params[:user]
      error :bad_request
    end
  end

  def error type, context=nil
    render json: { message: error_message(type, context) }, status: type
  end

  def error_message type, context
    scope = [:api, :error, self.controller_name.to_sym]
    scope.push context if context
    t(type, scope: scope)
  end

end

class Api::V1::BaseController < ApplicationController
  load_and_authorize_resource

  respond_to :json

  rescue_from CanCan::AccessDenied do |exception|
    render_status :unauthorized
  end

  private

  def error type, context=nil
    render json: {message: error_message(type, context)}, status: type
  end

  def error_message type, context
    scope = [:api, :error, self.controller_name.to_sym]
    scope.push context if context
    t(type, scope: scope)
  end

  def render_status state
    render status: state, json: {}
  end
end
\$\endgroup\$
2
\$\begingroup\$

Put the common error methods in a Module and include it in each Controller where you need them (in a similar way like you already include Devise::Controllers::Helpers, but this time with your own namespace and module name.)

As for the method signatures

def error type, context=nil
def error_message type, context
def render_status state

it's common to leave the parenthesis out when calling class methods in class context (because they oftentimes make up a nice DSL), but please don't do it when defining methods, that can lead to annoying ambiguities.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.