[ruby on rails] concerns的使用

  • concern是用来把公共的方法提取到一起,保持代码DRY,是用module来实现的

model中的concern

module Visible
  extend ActiveSupport::Concern

  VALID_STATUSES = ['public', 'private', 'archived']  # 其他地方引用  Visible::VALID_STATUSES
 
  # 关联关系 blongs_to, has_many 、validates、 scope 都需要写到 included block中
  included do
    belongs_to :user

    validates :status, inclusion: { in: VALID_STATUSES }
    validate do
      errors[:name] << '请输入名称' if name.to_s.splict(',').size < 2
    end
    
    scope :public_count, -> { where(status: 'public').count }
    
    # 类方法一
    def self.public_count
      where(status: 'public').count
    end
    
    # 类方法二
    class << self
      def public_count
        where(status: 'public').count
      end
    end
     
	# 实例方法
    def public?
      status == 'public'
    end
  end
  
  # 类方法三,写到 included 外面
  class_methods do
    def public_count
      where(status: 'public').count
    end
  end

  # 实例方法
  def archived?
    status == 'archived'
  end
end
  • 使用的时候include Visible
class User < ApplicationRecord
  include Visible
end
# 就可以使用了
User.public_count
user.archived?
module PubMethods
  extend ActiveSupport::Concern

  included do
    before_action :authenticate_user_using_x_auth_token

    rescue_from ActiveRecord::RecordNotFound do |e|
      json_response({ msg: e.message }, :not_found)
    end

    rescue_from StandardError, with: :handle_api_exception

    def handle_api_exception(exception)
      case exception
      when -> (e) { e.message.include?("PG::") || e.message.include?("SQLite3::") }
        handle_database_level_exception(exception)

      when ActionController::ParameterMissing
        render_error(exception, :internal_server_error)

      when ActiveRecord::RecordNotFound
        render_error(t("not_found", entity: exception.model), :not_found)

      when ActiveRecord::RecordNotUnique
        render_error(exception)

      when ActiveModel::ValidationError, ActiveRecord::RecordInvalid, ArgumentError
        error_message = exception.message.gsub("Validation failed: ", "")
        render_error(error_message, :unprocessable_entity)
      else
        handle_generic_exception(exception)
      end
    end

    def handle_generic_exception(exception, status = :internal_server_error)
      log_exception(exception) unless Rails.env.test?
      error = Rails.env.production? ? t("generic_error") : exception
      render_error(error, status)
    end
  end

  def json_response(object, status = :ok)
    render json: object, status: status
  end

  private

  def authenticate_user_using_x_auth_token
    user_email = request.headers["X-Auth-Email"].presence
    auth_token = request.headers["X-Auth-Token"].presence
    user = user_email && User.find_by!(email: user_email)
    is_valid_token = user && auth_token && ActiveSupport::SecurityUtils.secure_compare(user.authentication_token, auth_token)
    if is_valid_token
      @current_user = user
    else
      render_error(t("session.could_not_auth"), :unauthorized)
    end
  end

  def render_error(message, status = :unprocessable_entity, context = {})
    is_exception = message.kind_of?(StandardError)
    error_message = is_exception ? message.record&.errors_to_sentence : message
    render status: status, json: { error: error_message }.merge(context)
  end
end
  • 使用的时候include PubMethods
json_response({ msg: 'ok' })
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值