7

I'm trying to allow users to change their email addresses which devise uses as their unique username. Even though the update gives no errors, no change is made to the email address for the user in the database.

Here are the relevant portions of code:

Form:

<%= f.fields_for :user_account, @user.user_account do |user_account| %> 
<p>Edit email address for account: <%=  @user.user_account.email %></p> 
<div class="field">
  <%= user_account.label :new_email %><br />
  <%= user_account.text_field :email, autocomplete: "off", value: nil %>
</div>
<div class="field">
  <%= user_account.label :password %> <i>(please confirm the password associated with this account)</i><br />
  <%= user_account.password_field :current_password, autocomplete: "off" %>
</div>
<%= hidden_field_tag 'form', 'email' %>
<div class="actions">
  <%= user_account.submit "Edit" %>
</div>

controller:

def update
respond_to do |format|
if params[:form] == 'email'
    if @user.user_account.valid_password?(params[:user][:user_account_attributes][:current_password])
      if @user.update(user_params)
        format.html { redirect_to user_path(@user), :notice => 'your new email has been saved' }
        format.json { render :show, status: :ok, location: @user }
      else
        format.html { render :edit }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    else 
      format.html { redirect_to edit_email_path(@user), :notice => 'incorrect password (email)' }
    end 
else ...

the user_params method:

def user_params
params.require(:user).permit(
  :first_name, :middle_initial, :last_name, 
  :linkedin, :website, :facebook, :video, :phone_number, 
  :address_1, :address_2, :city, :zip_code, 
  :image, :number, :years_practicing, :neighborhood, :biography, :price, :status,
  user_employments_attributes: [:id, :user_id, :company, :position, :start_date, :end_date, :info, :_destroy], 
  user_educations_attributes: [:id, :user_id, :school, :degree_title, :start_date, :end_date, :info, :_destroy], 
  user_account_attributes: [:id, :user_id, :email, :password, :password_confirmation, :_destroy], 
  user_category_ids:[])
end

user account model:

 class UserAccount < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # , :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable, :confirmable,
     :recoverable, :rememberable, :trackable, :validatable
   belongs_to :user
 end
chris
  • 1,869
  • 4
  • 29
  • 52

2 Answers2

8

Ok, so it turns out that the new email address was being saved as :unconfirmed_email, but this did not change any of the functionality of the linked account, since the account still had the old email stored as :email.

Thus I had to do

user.confirmed_at = nil
user.save(:validate => false)

in order for the user confirmation email to be resent and so that the login form would no longer accept the old password.

chris
  • 1,869
  • 4
  • 29
  • 52
0

I am not sure, but I think, in your user model there should be

accepts_nested_attributes_for :user_account
McSvenster
  • 165
  • 1
  • 8