如何从基于Devise的会话控制器中删除重复的方法?

时间:2013-07-09 11:45:40

标签: ruby-on-rails ruby devise refactoring

我有移动设备的会话控制器。我想稍微重构一下,例如因为我的会话控制器是Devise::SessionsController的子类我不得不从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

1 个答案:

答案 0 :(得分:1)

我建议将常用方法提取到模块并包含它。

module CommonMethods
  def self.included(controller)
    controller.send :error_message, :error
  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

只需在控制器中加入include CommonMethods

即可