0
votes

Devise won't save new email or password using default code added when I ran the generator. I discovered that after adding first, middle and last name fields and then starting over. The default code is:

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>

I added a few fields to the registrations/edit form, specifically :first_name, :middle_name, and :last_name

Following other examples found on Stackoverflow, I changed the resource name and path in the views/users/registrations/edit.html.erb file.:

<%= form_for(@user, as: :update, url: users_path(params[:id]), html: { method: :put, :multipart => true }) do |f| %>

Devise is at the top of my config/routes file with scope:

devise_for :users
devise_scope :user do
  put "update", to: 'devise/registrations#update', as: :update
end

In the ApplicationController, I sanitize the params - those required for signup and the ones I added:

protected
  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:users) { |u| u.params.permit(:id,
    :email, :password, :password_confirmation)}

    devise_parameter_sanitizer.for(:users) { |u| u.permit(
    :first_name, :middle_name, :last_name) }
  end
end

I also put the customary before_filter at the top of the ApplicationController:

 before_action :configure_permitted_parameters, if: :devise_controller?

Here's the update method:

def update
  @user = User.find(params[:id])

  if params[:user][:password].blank?
    params[:user].delete(:password)
    params[:user].delete(:password_confirmation)
  end

  if @user.update_attributes(users_params)
      sign_in(current_user, :bypass => true) if @user == current_user
      @user.save
      flash[:success] = "Profile Updated!"
      redirect_to user_path
  else
    redirect_to edit_user_path
  end
end

Here's the rails server output. (I used "my best friend" for first, middle, and last name.):

Started GET "/users/edit?update%5Bname%5D=User+Example&update%5Bfirst_name%5D=my&update%5Bmiddle_name%5D=best&update%5Blast_name%5D=friend&commit=Update" for ::1 at 2015-01-28 18:54:57 -0600<br/>

Processing by Devise::RegistrationsController#edit as HTML
Parameters: {"update"=>{"name"=>"User Example", "first_name"=>"my", "middle_name"=>"best", "last_name"=>"friend"}, "commit"=>"Update"}
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Rendered users/registrations/edit.html.erb within layouts/application (6.1ms)
Rendered shared/_bootstrap.html.erb (0.1ms)
Rendered shared/_html5_shim.html.erb (0.0ms)
Rendered layouts/_navigation_top.html.erb (1.1ms)
Rendered layouts/_messages.html.erb (0.1ms)
Rendered shared/_navigation_bottom.html.erb (0.5ms)
Rendered shared/_jquery_and_js.html.erb (0.1ms)
Completed 200 OK in 472ms (Views: 468.8ms | ActiveRecord: 0.6ms)

Viewing the user in rails console shows the value for first, middle, and last name as 'nil'. Also, trying to change the email or password doesn't work. New users can sign up and their email and password are saved.

I'm confused why this didn't just work after installing devise. That said, how do I fix it so that a user can change their email, password, or add their first, middle, and last names? Thank you in advance.

2

2 Answers

0
votes

Don't know about other stuff going on here (you got a lot of customization), but the first thing that seems to me wrong:

you permit :users as a root in params: devise_parameter_sanitizer.for(:users) { |u| u.params.permit(:id, :email, :password, :password_confirmation)} but create a form using :update (???) as a root for the param hash:
<%= form_for(@user, as: :update, url: users_path(params[:id]), html: { method: :put, :multipart => true }) do |f| %>


Change the form to <%= form_for(@user, as: :user, url: users_path(params[:id]), html: { method: :put, :multipart => true }) do |f| %> first

0
votes

I inadvertently - sometime ago - removed the _form.html.erb partial that devise places in the views/users folder. I then also removed the link from the users/edit.html.erb file to the partial. I had to scaffold a new project in order to figure this one out. It wasn't a routing error.