#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