Параметры действия Rails [: user] не указаны, как вернуть ошибку

#ruby-on-rails #ruby #controller

#ruby-on-rails #ruby #контроллер

Вопрос:

Я работаю над проектом, в котором я хочу убедиться, что если в запросе нет пользовательских параметров, он должен отправить ошибку, поэтому я использовал следующий метод в контроллере

 class UsersController < ApplicationController
  before_action :check_params

  private

  def user_params
    params.require(:user).permit(:email, :password)
  end

  def check_params
    render json: { error: 'No user params provided' }, status: 401 unless params[:user]
  end
end
 

Он работает нормально, но я должен установить на каждый отдельный контроллер, есть ли способ добавить его в приложение для всех контроллеров! поскольку только params[:user] меняется, поэтому, если у меня есть params[:company] , мне нужно добавить другой метод в CompaniesController с параметрами [:company], которые на самом деле не являются сухими. Я удивлен, когда мы используем params.require(:user), почему он выдает ошибки, а не возвращает ошибку проверки.

Комментарии:

1. Если имена параметров и сообщение об ошибке разные в разных контроллерах — проще иметь собственный check_params контроллер с разными параметрами. check_params в разных контроллерах это не одно и то же, это не нарушит DRY, потому что методы будут меняться по разным причинам.

2. Да, но, возможно, мы можем уменьшить количество кода, поскольку он выполняет ту же функциональность, просто изменяя один символ :user

3. Зачем вам нужно проверять это вручную? Когда вы используете StrongParams (как вы это делаете), и вы вызываете params.require(:user) , а в параметрах нет такого ключа, тогда ActionController::ParameterMissing будет вызвано исключение, которое уже должно охватывать ваш usecase.

4. @spickermann Я хочу показывать не это исключение, а сообщение об ошибке json.

Ответ №1:

Я выгляжу так, как будто вы хотите выполнить спасение ActionController::ParameterMissing с помощью пользовательского сообщения об ошибке. Способ Rails сделать это — rescue_from метод.

Добавьте следующее в свой контроллер:

 rescue_from 'ActionController::ParameterMissing' do |exception|
  render json: { error: 'No user params provided' }, status: 401
end
 

Ответ №2:

Ну, вместо того, чтобы создавать весь этот метод, вы можете просто проверить, где ваше действие проверяет параметры [: user] и отклоняет в одной строке, например, следующее

 @user = User.find_by_email(params[:user][:email]) if params[:user]
 

Теперь он не будет искать ваши параметры [:user]

Ответ №3:

Вы можете переместить общую логику в метод в базовом классе, тогда производные классы могут передавать ему собственные «изменяемые» переменные или игнорировать метод

 class ApplicationController
  def check_params(name, error_message)
    render json: { error: error_message }, status: 400 if params[name].nil?
  end
end
 

Использование

 class UsersController < ApplicationController
  before_action -> { check_params(:user, "User is missing") }
end