class ApplicationController < ActionController::API rescue_from ActiveRecord::RecordInvalid, with: :render_record_invalid rescue_from ActiveRecord::RecordNotUnique, with: :render_record_not_unique before_action :reject_banned_ip_address! before_action :authenticate_user before_action :reject_banned_user! def current_user = @current_user private def authenticate_user code = request.headers['X-Transfer-Code'] || request.headers['HTTP_X_TRANSFER_CODE'] return if code.blank? @current_user = User.find_by(inheritance_code: code) end def bool? key, default: false return default if params[key].nil? s = params[key].to_s.strip.downcase if default !(s.in?(['0', 'false', 'off', 'no'])) else s.in?(['', '1', 'true', 'on', 'yes']) end end def render_bad_request message = 'リクエストが不正です.', field: nil, code: :bad_request render_error(:bad_request, message, field:, code:) end def render_unprocessable_entity message = '入力を確認してください.', field: nil, code: :invalid render_error(:unprocessable_entity, message, field:, code:) end def render_error status, message, field: nil, code: status error = { code: code.to_s, message: } error[:field] = field.to_s if field.present? render json: { errors: [error] }, status: end def render_model_errors record, status: :unprocessable_entity errors = record.errors.map do |error| { code: error.type.to_s, field: error.attribute.to_s, message: error.full_message } end errors = [{ code: 'invalid', message: '入力を確認してください.' }] if errors.empty? render json: { errors: }, status: end def render_record_invalid error render_model_errors(error.record) end def render_record_not_unique _error = nil render_unprocessable_entity('既に存在してゐます.', code: :taken) end def reject_banned_ip_address! ip_address = IpAddress.find_by(ip_address: IPAddr.new(request.remote_ip).hton) return unless ip_address&.banned? head :forbidden end def reject_banned_user! return unless current_user&.banned? head :forbidden end def render_validation_error record = nil, fields: { }, base: [] errors = { } if record record.errors.messages.each do |attr, messages| errors[attr] ||= [] errors[attr].concat(messages) end end fields.each do |attr, messages| errors[attr] ||= [] errors[attr].concat(Array(messages)) end base_errors = Array(base) - Array(errors.delete(:base)) render json: { type: 'validation_error', message: '入力内容を確認してください.', errors:, base_errors: }, status: :unprocessable_entity end end