0

私の目標は、(ログインしている) ユーザーが、ページから移動せずに、電子メールまたはパスワードを (別々のフォームで、両方を同時にではなく) 更新することを選択できるプロファイル ページを作成することです。

メールの更新は、新しいメール アドレスを入力して [変更を保存] 送信ボタンをクリックするだけで簡単に行えます。

パスワードを更新するには、ユーザーは古いパスワード、新しいパスワード、および新しいパスワードの確認を入力し、[パスワードの更新] ボタンを押す必要があります。問題は update_pwd メソッドにあるはずです。

users_controller.rb

# ...

def edit # template: edit.html.erb
    @user = User.find(current_user)
end

def update_email
    @user = User.find(current_user)
    if params[:commit] == 'Save Changes'
        if @user.update_attributes(user_params_email)
            redirect_to me_url
            flash[:notice] = "Your changes have been saved"
        else # either invalid or taken
            render :edit
        end
   else 
        render :edit
   end
end

def update_pwd
    @user = User.find(current_user)
    if params[:commit] == 'Update Password' 
        if @user.update_attributes(user_params_pwd) && User.find_by(username: current_user.username).try(:authenticate, params[:current_password])
            redirect_to me_url
            flash[:notice] = "Password updated!"
        else
            flash.now[:alert] = @user.errors.full_messages[0]
            render :edit
        end
    else
        render :edit
    end
end

private

#def user_params
    #params.require(:user).permit(:id, :username, :email, :password, :password_confirmation)
#end

def user_params_email
    params.require(:user).permit(:email)
end

def user_params_pwd
    params.require(:user).permit(:password, :password_confirmation, :current_password)
end

edit.html.erb

<%= form_for(current_user, :url => {:controller => 'users', :action => 'update_email'}) do |f| %>

    <% if @user.errors.any? %>
        <% for message in @user.errors.full_messages %>
            <li><%= message %></li>
        <% end %>
    <% end %>

    <p> Current Email: <%= current_user.email %> </p>
    <p> New Email: <%= f.text_field :email %> </p>

   <%= f.submit "Save Changes" %>

<% end %>

<%= form_for(current_user, :url => {:controller => 'users', :action => 'update_pwd'}) do |g| %>

    <p>Old Password<br>
    <%= password_field_tag :current_password, params[:password] %></p>
    <p>New Password<br>
    <%= g.password_field :password %></p>
    <p>Confirm New Password<br>
    <%= g.password_field :password_confirmation %></p>

    <%= g.submit "Update Password" %>
<% end %>

ルート.rb

# ...
get '/me' => 'users#edit'
patch '/me' => 'users#update_email'
patch '/me' => 'users#update_pwd'
# ...

これで、電子メールの更新を希望どおりに機能させることができました (必要なエラー メッセージ/検証などを使用)。ただし、パスワードの更新ボタンをクリックすると、ビューがレンダリングされますが、何も起こりません。代わりに、 update_email 関数が呼び出されているように見えます。

Started PATCH "/me" for ::1 at 2015-05-20 10:34:31 -0500
Processing by UsersController#update_email as HTML
Parameters: {"utf8"=>"V", "authenticity_token"=>"msEsj6yxfdrbXjjdm6cH3JamrFU8R1EoZ5asmE831GSxLwpiiIW/wmGrr9HiQxFDySJtW5MKK6Ezq9hZaMNFtA==", "current_password"=>"[FILTERED]", "user"=>{"password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Update Password"}
←[1m←[36mUser Load (0.0ms)←[0m  ←[1mSELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1←[0m  [["id", 2]]
DEPRECATION WARNING: You are passing an instance of ActiveRecord::Base to `find`. Please pass the id of the object by calling `.id`. (called from update_email ...)

user.rb

# ...

has_secure_password

validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }   
validates_uniqueness_of :email

validates :password, length:{ minimum: 8 }, on: :create
validates :password_confirmation, presence: true, on: :create
# ...

application_controller.rb

# ...
helper_method :current_user

private

def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
    rescue ActiveRecord::RecordNotFound
end

エラーログ (上記参照)

Started PATCH "/me" for ::1 at 2015-05-20 10:34:31 -0500
Processing by UsersController#update_email as HTML
Parameters: {"utf8"=>"V", "authenticity_token"=>"msEsj6yxfdrbXjjdm6cH3JamrFU8R1EoZ5asmE831GSxLwpiiIW/wmGrr9HiQxFDySJtW5MKK6Ezq9hZaMNFtA==", "current_password"=>"[FILTERED]", "user"=>{"password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Update Password"}
←[1m←[36mUser Load (0.0ms)←[0m  ←[1mSELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1←[0m  [["id", 2]]
DEPRECATION WARNING: You are passing an instance of ActiveRecord::Base to `find`. Please pass the id of the object by calling `.id`. (called from update_email ...)
4

1 に答える 1