Reputation: 953
I have weird problem, previous created form instead of updating user details such as e-mail or name creates new user with given details.
My form: this code example I took from views/devise/registrations/edit
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { "data-parsley-validate" => true, :id=>"user-edit"},remote: true, format: :json) do |f| %>
<div class="form-group">
<%= f.text_field :name,:class=>"user-input form-control", :id=>"user-name" ,:placeholder=> "Lietotājvārds*",:"data-parsley-group"=>"f1" %>
</div>
<div class="form-group">
<%= f.email_field :email ,:class=>"user-input form-control", :id=>"password",:placeholder=> "E-pasts *",:"data-parsley-group"=>"f2" %>
</div>
<div class="form-group">
<%= f.password_field :current_password, :autocomplete => "off" ,:class=>"user-input form-control", :id=>"password",:placeholder=> "Vecā parole* ",:"data-parsley-group"=>"f3" %>
</div>
<div class="form-group">
<%= f.password_field :password , :class=>"user-input form-control", :id=>"password",:placeholder=> "Jaunā parole* vismaz 8 simboli ", :"data-parsley-group"=>"f3" %>
</div>
<div class="form-group">
<%= f.password_field :password_confirmation , :class=>"user-input form-control", :id=>"password",:placeholder=> "Atkārtot paroli * vismaz 8 simboli ", :"data-parsley-group"=>"f3" %>
</div>
<button type="submit" class="blue-button btn btn-default">Apstiprināt</button>
<%end%>
Routes file:
devise_for :users, :controllers => {:registrations=> "registrations"}
Registration controller:
class RegistrationsController < Devise::RegistrationsController
clear_respond_to
respond_to :json
def sign_up_params
params.require(:user).permit( :email, :password, :password_confirmation,:name, :not_a_robot,:current_password,:bypass_humanizer)
end
def account_update_params
params.require(:user).permit(:name, :email, :password, :password_confirmation, :current_password, :not_a_robot, :bypass_humanizer)
end
private :sign_up_params
private :account_update_params
protected
def update_resource(resource, params)
resource.update_without_password(params)
end
end
In applicaion helper:
module ApplicationHelper
def resource_name
:user
end
def resource
@resource ||= User.new
end
def devise_mapping
@devise_mapping ||= Devise.mappings[:user]
end
end
Log file:
Started POST "/ru/users" for 85.255.65.15 at 2015-09-28 19:32:25 +0300
Processing by RegistrationsController#create as JS
Parameters: {"utf8"=>"✓", "user"=>{"name"=>"ooppapa", "email"=>"test11@!!!", "current_password"=>"[FILTERED]", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "bypass_humanizer"=>"true", "not_a_robot"=>"1"}, "locale"=>"ru"}
[1m[36mBanlist Load (2.0ms)[0m [1mSELECT `banlists`.* FROM `banlists` WHERE (ip_adress = '85.255.65.15')[0m
[1m[35mCountry Load (1.5ms)[0m SELECT `countries`.* FROM `countries` WHERE `countries`.`id` = 1 LIMIT 1
[1m[36mRegion Load (1.3ms)[0m [1mSELECT `regions`.* FROM `regions` WHERE `regions`.`country_id` = 1[0m
[1m[35m (0.4ms)[0m BEGIN
[1m[36mUser Exists (44.1ms)[0m [1mSELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 'test11@!!!' LIMIT 1[0m
[1m[35mUser Load (24.3ms)[0m SELECT `users`.* FROM `users` WHERE `users`.`confirmation_token` = '5c5e282bd4c139c7764506b785d54119ceee5499426b555c3650cfc7190ee947' ORDER BY `users`.`id` ASC LIMIT 1
[1m[36mSQL (2.1ms)[0m [1mINSERT INTO `users` (`confirmation_sent_at`, `confirmation_token`, `created_at`, `email`, `encrypted_password`, `name`, `updated_at`) VALUES ('2015-09-28 19:32:29', '5c5e282bd4c139c7764506b785d54119ceee5499426b555c3650cfc7190ee947', '2015-09-28 19:32:28', '[email protected]', '$2a$10$mEHajmY0H1NueGrrap7NNu0LuViDEJ.imAS4jhdj1KIyPRIyej/NC', 'ooppapa', '2015-09-28 19:32:28')[0m
Rendered devise/mailer/confirmation_instructions.html.erb (29.2ms)
Devise::Mailer#confirmation_instructions: processed outbound mail in 1726.8ms
Sent mail to test11@!!!.eu (776.1ms)
Date: Mon, 28 Sep 2015 19:32:31 +0300
From: support@!!!!.eu
Reply-To: support@!!!!.eu
To: test11@!!!!.eu
Message-ID: <56096b9f98eb5_25e4640a718550c6@!!!!!>
Subject: Confirmation instructions
Mime-Version: 1.0
Content-Type: text/html;
charset=UTF-8
Content-Transfer-Encoding: 7bit
<p>Welcome !!!</p>
<p>You can confirm your account email through the link below:</p>
My routes:
rake routes
new_user_session GET (/:locale)/users/sign_in(.:format) devise/sessions#new {:locale=>/lv|ee|ru/}
user_session POST (/:locale)/users/sign_in(.:format) devise/sessions#create {:locale=>/lv|ee|ru/}
destroy_user_session DELETE (/:locale)/users/sign_out(.:format) devise/sessions#destroy {:locale=>/lv|ee|ru/}
user_password POST (/:locale)/users/password(.:format) devise/passwords#create {:locale=>/lv|ee|ru/}
new_user_password GET (/:locale)/users/password/new(.:format) devise/passwords#new {:locale=>/lv|ee|ru/}
edit_user_password GET (/:locale)/users/password/edit(.:format) devise/passwords#edit {:locale=>/lv|ee|ru/}
PATCH (/:locale)/users/password(.:format) devise/passwords#update {:locale=>/lv|ee|ru/}
PUT (/:locale)/users/password(.:format) devise/passwords#update {:locale=>/lv|ee|ru/}
cancel_user_registration GET (/:locale)/users/cancel(.:format) registrations#cancel {:locale=>/lv|ee|ru/}
user_registration POST (/:locale)/users(.:format) registrations#create {:locale=>/lv|ee|ru/}
new_user_registration GET (/:locale)/users/sign_up(.:format) registrations#new {:locale=>/lv|ee|ru/}
edit_user_registration GET (/:locale)/users/edit(.:format) registrations#edit {:locale=>/lv|ee|ru/}
PATCH (/:locale)/users(.:format) registrations#update {:locale=>/lv|ee|ru/}
PUT (/:locale)/users(.:format) registrations#update {:locale=>/lv|ee|ru/}
DELETE (/:locale)/users(.:format) registrations#destroy {:locale=>/lv|ee|ru/}
user_confirmation POST (/:locale)/users/confirmation(.:format) devise/confirmations#create {:locale=>/lv|ee|ru/}
new_user_confirmation GET (/:locale)/users/confirmation/new(.:format) devise/confirmations#new {:locale=>/lv|ee|ru/}
GET (/:locale)/users/confirmation(.:format) devise/confirmations#show {:locale=>/lv|ee|ru/}
update_password_user PATCH (/:locale)/user/update_password(.:format) users#update_password {:locale=>/lv|ee|ru/}
edit_user GET (/:locale)/user/edit(.:format) users#edit {:locale=>/lv|ee|ru/}
sms_receive GET (/:locale)/sms/receive(.:format) sms#receive {:locale=>/lv|ee|ru/}
root GET /(:locale)(.:format) girls#index {:locale=>/lv|ee|ru/}
I am confused. Is it registration_path(resource_name) that creates this error?
Any advise could be helpful.! thanks in advance.
Upvotes: 3
Views: 2972
Reputation: 906
I saw your question and maybe the problem is on form call.
Try insert html: { method: :put }
. With simple_form I use this way:
= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f|
How you omitted the method of send the form, it's sending as post and creating a new record, I presume.
Upvotes: 1
Reputation: 14943
The issue is in the form as it is pointing to the registration_path(resource_name)
path.
The example you are using is taken from How To: Allow users to edit their account without providing a password and it says:
and provide an edit and update actions, as you would do for any other resource in your application.
Which means you need to create a route to the edit method and use it as you wish.
The example above is for updating the user without the password, but what you are doing is updating the password.
For the solutions, read How To: Allow users to edit their password
An example solution - #3:
UsersController
class UsersController < ApplicationController
before_filter :authenticate_user!
def edit
@user = current_user
end
def update_password
@user = User.find(current_user.id)
if @user.update(user_params)
# Sign in the user by passing validation in case their password changed
sign_in @user, :bypass => true
redirect_to root_path
else
render "edit"
end
end
private
def user_params
# NOTE: Using `strong_parameters` gem
params.require(:user).permit(:password, :password_confirmation)
end
end
If you are using several scopes, specify the one you are signing in:
sign_in :user, @user, bypass: true
The route should be the following:
resource :user, only: [:edit] do
collection do
patch 'update_password'
end
end
View
<%= form_for(@user, :url => { :action => "update_password" } ) do |f| %>
<div class="field">
<%= f.label :password, "Password" %><br />
<%= f.password_field :password, :autocomplete => "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %>
</div>
<div class="action_container">
<%= f.submit %>
</div>
<% end %>
To use "confirm_password" field to force user to enter old password before updating with the new one: Change
@user.update(user_params)
to@user.update_with_password(user_params)
in the controller along with adding:current_password
to the permitted parameters, then and add the following to the view code:
<div class="field">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password %>
</div>
Remember, Devise models are like any model in your application. If you want to provide custom behavior, just implement new actions and new controllers. Don't try to bend Devise.
Upvotes: 3