The password field is ignored when I use fetch or require

Hello,

I am trying to authenticate using has_secure_password, but when I send a payload as shown below, I cannot access the password field.

{
 "email": "foo@example.com",
 "name": "Chazy Ches",
 "password": "secureP@ssword",
 "phone_number": "+1234567890"
}

My parameter configuration is as follows

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

The parameters handled in the “user” object in the Rails log appear like this.

Processing by UsersController#create as JSON
  Parameters: {"email"=>"foo@example.com", "name"=>"Chazy Ches", "password"=>"[FILTERED]", "phone_number"=>"+1234567890", "user"=>{"name"=>"Chazy Ches", "email"=>"foo@example.com", "phone_number"=>"+1234567890"}}

As you can see, there is no “password” in the “user” object. And I get a validation error because ‘password’ is not returned from the user params method.

{
  "user": {
    "email": "foo@example.com",
    "name": "Chazy Ches",
    "password": "secureP@ssword",
    "phone_number": "+1234567890"
  }
}

It works this way, but I do not want to send the payload inside the user object.

How can I solve this problem? Thanks.

If you cannot or do not want to change the JSON structure that is being sent to your API, you can adjust the controller to handle a flat JSON structure by modifying the user_params method to directly permit the parameters without requiring them to be nested under a user key:

def user_params
  params.permit(:name, :email, :password, :phone_number)
end

This approach deviates from typical Rails conventions but can be useful in situations where you have less control over the format of the incoming JSON, such as when interfacing with external systems.

Personally, I would just nest it in the JSON ‘user’ object. It’s generally best practice in Rails to use nested parameters for creating or updating records. This approach offers better organization and security, especially when you start dealing with complex forms and nested attributes.

Since you are using has_secure_password, ensure that the password_digest attribute is correctly set up in your model, and the bcrypt gem is included in your Gemfile. This setup should automatically handle the encryption of the password when password is provided in the user parameters.

If you choose to adjust your JSON payload structure, remember to update any clients or documentation that send data to your API to ensure they align with these expectations.