Ruby on Rails 6中API验证错误响应格式自定义实现问题咨询
Hey there! Let's walk through how to get your exact desired error response format. You're close already—we just need to tweak two parts: simplifying the error array-to-string conversion, and adjusting the first_name error message to include the friendly attribute name.
Step 1: Simplify Error Formatting in the Controller
Your current code uses map to convert error arrays to single strings, but Rails has a cleaner built-in method for this: transform_values. This method lets you modify every value in a hash with minimal, idiomatic code.
Update your rescue_from block like this:
rescue_from ActiveRecord::RecordInvalid do |exception| # Convert each error array to its first (and only) message string formatted_errors = exception.record.errors.messages.transform_values(&:first) @response = { status: Status.bad_request, message: Message.profile_not_updated, errors: formatted_errors } json_response(@response, :bad_request) end
This does exactly what your original map code did, but it's more readable and aligns with standard Rails practices.
Step 2: Customize the First Name Error Message
Right now, Rails generates the default "is too short..." message for first_name. To get "firstname is too short..." instead, you have two options depending on how scalable you want the solution to be:
Option 1: Directly Customize in the Model
If you only need this change for first_name, add a custom too_short message to its validation (split out the shared validations to avoid affecting other attributes):
# Model code validates :first_name, presence: true, length: { minimum: 3, maximum: 25, too_short: "firstname is too short (minimum is %{count} characters)", too_long: "firstname is too long (maximum is %{count} characters)" } # Keep validations for other attributes as-is validates :last_name, :state, :referral_method, presence: true, length: { minimum: 3, maximum: 25 } validates :phone_number, format: { with: VALID_PHONE_REGEX, message: "Enter a valid us phone number" }, if: :phone_number_changed?
This isolates the custom message to just first_name without altering error messages for other fields.
Option 2: Use Locale Files (Scalable for Multiple Attributes)
If you want to add friendly attribute names to all your error messages (e.g., "lastname is too short..." for last_name), edit your config/locales/en.yml file. This is the Rails-recommended way for consistent, maintainable error messaging:
en: activerecord: attributes: # Replace `profile` with your actual model name profile: first_name: "firstname" last_name: "lastname" state: "state" referral_method: "referral method" errors: models: profile: attributes: first_name: too_short: "is too short (minimum is %{count} characters)" too_long: "is too long (maximum is %{count} characters)" # Add similar entries for other attributes if needed errors: format: "%{attribute} %{message}"
The format: "%{attribute} %{message}" line tells Rails to combine the friendly attribute name (from the attributes section) with the error message, giving you exactly the format you want.
Final Result
With these changes, your error response will match exactly what you're looking for:
{ "status": 400, "message": "Profile update was unsuccessfull", "errors": { "first_name": "firstname is too short (minimum is 3 characters)", "phone_number": "Enter a valid us phone number" } }
内容的提问来源于stack exchange,提问作者Praise

