I am using Devise & I am trying to create a new form where user's can reset their passwords, but I am getting the following error:
ActiveRecord::RecordNotUnique (PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_users_on_reset_password_token"
The reason this is happening is because the reset_password_token generated from
<%= f.hidden_field :reset_password_token %>
is empty. Ex:
<input id="user_reset_password_token" name="user[reset_password_token]" type="hidden">
Here is the controller action
def update_password
#user = current_user
# raise params.inspect
if #user.update_with_password(params[:user])
sign_in(#user, :bypass => true)
redirect_to '/account_settings', :notice => "Your Password has been updated!"
else
redirect_to '/account_settings', :notice => "Your Password was not changed. Try again"
end
end
Here is my form
edit_password.html.erb
<ul class="nav nav-pills">
<li class="active">Change Password</li>
<li>Profile</li>
<li>Messages</li>
</ul>
<hr/>
<%= render :template => 'users/edit_password_form',
:locals => { :resource => current_user, :resource_name => "user" } %>
edit_password_form.html.erb
<%= form_for(resource, :as => resource_name, :url => "password/users/update_password", :html => { :method => :put }) do |f| %>
<%# devise_error_messages! %>
<%= f.hidden_field :reset_password_token %>
<br>
<div class="row">
<div class="col-sm-3 col-md-3 ">
<%= f.label :current_password, "Current Password:" %>
</div>
<div class="col-sm-3 col-md-3 ">
<%= f.password_field :current_password, :placeholder =>"Current Password" %>
</div>
</div>
<br>
<div class="row">
<div class="col-sm-3 col-md-3 ">
<%= f.label :password, "New Password:" %>
</div>
<div class="col-sm-3 col-md-3 "><%= f.password_field :password, :placeholder=>"New Password" %>
</div>
</div>
<br>
<div class="row">
<div class="col-sm-3 col-md-3 ">
<%= f.label :password_confirmation, "Confirm New Password:" %>
</div>
<div class="col-sm-3 col-md-3 ">
<%= f.password_field :password_confirmation, :placeholder=>"Confirm New Password" %>
</div>
</div>
<br>
<br>
<%= f.submit "Change my password", :class => "btn btn-default" %>
<% end %>
I assume this has nothing to do with the built-in devise functionality where they can be sent an email to reset their password when they've forgotten it. Instead, it looks like you are allowing them to enter their current password and then choose a new one. In that case, I don't think you want the reset_password_token in the form at all, as it's irrelevant, i.e. you can just remove the line:
<%= f.hidden_field :reset_password_token %>
Related
I'm new to ruby on rails.
I've two type of users Admin and User. Admin can create edit and destroy user. I've no problem with create and destroy and have implemented quite easily.
I've used following code in controller,
private
def allowed_params
params.require(:user).permit(:role_id, :email, :password, :password_confirmation, :fname, :lname)
end
to define parameters required and allowed while creating user.
User Create
def save_user
#user = User.new(allowed_params)
if #user.save
redirect_to list_users_path
else
render 'add_user'
end
end
User Update
def update_user
#user = User.find(params[:id])
if #user.update_attributes(allowed_params)
redirect_to list_users_path
else
render 'edit_user'
end
end
View
<div class="container">
<div class="row">
<div class="col-md-12">
<%= link_to "Admin Dashboard", admin_dashboard_path, :class=>'pull-left' %>
<%= form_for #user, :url => update_user_path do |f| %>
<div class="row">
<div class="col-md-12 field">
<div class="col-md-3">
<h2 style="text-align: center;">Edit User Details</h2>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 field">
<div class="col-md-3">
<%= f.label :fname, 'First Name' %><br />
<%= f.text_field :fname, :class => 'form-control' %>
<p class="error"><%= show_errors(#user, :fname) %></p>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 field">
<div class="col-md-3">
<%= f.label :lname, 'Last Name' %><br />
<%= f.text_field :lname, :class => 'form-control' %>
<p class="error"><%= show_errors(#user, :lname) %></p>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 field">
<div class="col-md-3">
<%= f.label :email, 'Email' %><br />
<%= f.text_field :email, :class => 'form-control' %>
<p class="error"><%= show_errors(#user, :email) %></p>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12 field">
<div class="col-md-3" style="text-align: center">
<%= f.submit "Update User", :class => 'btn btn-sm btn-primary' %>
</div>
</div>
</div>
<% end %>
</div>
</div>
</div>
when I pass only fname, lname and email nothing happened. I need to update user details what should I do here ?
Any suggestion is appreciated.
There is a debug way.
You should launch the server in development mode. Then check the changes of development.log file in the terminal by tail -f log/development.log.
Then do what you want, such as click the "submit" button when you changed the fname or other fields.
Then focus on the informations got on step 1. There are what you can get:
A. which Controller and action handled the request
B. The parameters of this request.
C. The log of SQLs excuted by DB
D. The response status
Check if the right Controller? or right parameters? or SQLs has been excuted? In addition, we used to #user.update_attributes!(allowed_params) when debug. It take more informations when something disobeys the rules defined in Model(User).
I have a problem with customising Devise method. I want to edit an existing profile. But it doesn't change.
Here's my code
My controller:
class DashboardController < Users::RegistrationsController::ApplicationController
def index
end
def update
#user = current_user
if #user.update_attributes(user_params)
redirect_to 'index', :notice => "Successfully updated profile."
else
Rails.logger.info(#user.errors.messages.inspect)
render :action => 'edit'
end
end
def edit
end
private
def user_params
params.require(:user).permit(:avatar, :username, :email, :password, :password_confirmation)
end
end
My edit view
<div class="container sign-in-up">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<br>
<div class="text-center">
<h1><b>Edit the profile</b> </h2>
<div class="tab-content">
<div class="tab-pane fade in active" id="new">
<fieldset>
<div class="form-group">
<div class="right-inner-addon">
<i class="fa fa-envelope"></i>
<%= form_for current_user, url: edit_dashboard_path(current_user), html: { method: :get, multipart: true } do |f|%>
<div class="home_field " >
<%= f.label :username%>
<br/>
<%= f.text_field :username, autofocus: true, :placeholder => 'Username', class:"form-control input-lg " %>
</div>
<div class="home_field ">
<%= f.label :email %>
<br/>
<%= f.email_field :email, autofocus: true, :placeholder => 'Email' , class:"form-control input-lg" %>
</div>
<div class="home_field ">
<%= f.label :password%>
<br/>
<%= f.password_field :password, :placeholder => 'Password', class:"form-control input-lg"%>
</div>
<div class="home_field ">
<%= f.label :password_confirmation%>
<br/>
<%= f.password_field :password_confirmation,:placeholder => 'Confirm your password' , class:"form-control input-lg"%>
</div>
<div class ="home_field">
<%= f.file_field :avatar %>
<br>
</div>
<div>
</div>
<div class="home_field">
<%= f.submit 'Edit the profile', class: "btn btn-primary btn-lg btn-block btn-group" %>
<br/>
</div>
<% end %>
</fieldset>
It can be a problem in my layout code, where i make the link to the edit page
<%= link_to "Edit the Profile", edit_dashboard_path %>
Your form is submitting to the edit dashboard using a get, which is the same page you are on. Instead you want to update the current user something like this:
<%= form_for current_user, html: { multipart: true } do |f|%>
This will default to the update attribute and CRUD action defined in your routes file for a user
I would suggest changing this line:
<%= form_for current_user, url: edit_dashboard_path(current_user), html: { method: :get, multipart: true } do |f|%>
In the url use your path to the 'update' method, not the edit (use rake routes on your command line)
In the method use :put instead of :get
I have two forms on my rails app that require a user to enter a code to confirm that they belong to a school and in the other form a code for a classroom. Every time a user enters or leaves the code blank I get this error message:
First argument in form cannot contain nil or be empty
It's always in the create method of the controller so I must not have the correct syntax.
Here are the two controllers where the error occurs.
Registration Controller
class RegistrationsController < Devise::RegistrationsController
skip_before_filter :verify_authenticity_token, :only => :create
def update
super
end
def new
super
end
def create
code = params[:user][:code]
#school = School.where(:code => code).first
unless #school
flash[:error] = "School code not valid"
render :new
end
params[:user][:school_id] = #school.id
super
end
School controller
def create_teacher
authorize #school
params[:user][:school_id] = #school.id
params[:user][:role] = "teacher"
#teacher = User.create(teacher_params)
if #teacher.id.nil?
flash[:error] = #teacher.errors.full_messages
render :new_teacher
else
respond_with #school
end
end
How do I correct this issue so that it renders a flash error message?
EDIT Screen Shots of actual error. Note, they are both in the create method so I think it's an identical problem.
EDIT: Registration form for adding users to schools.
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">
<h1>Sign up</h1>
</div>
<div class="panel-body">
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, autofocus: true, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.email_field :email, autofocus: true, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :school_code %>
<%# f.text_field :code, class: "form-control" %>
<input type="text" id="code" name="user[code]" value>
</div>
<div class="form-group">
<%= f.label :password %>
<%= f.password_field :password, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :password_confirmation, "Confirm Password" %>
<%= f.password_field :password_confirmation, class: "form-control" %>
</div>
<strong>Student</strong> <%= f.radio_button(:role, "user") %>
<div class="form-group">
<%= f.submit "Sign up", class: "btn btn-lg btn-primary" %>
</div>
<% end %>
</div>
<div class="panel-footer">
<%= render "devise/shared/links" %>
</div>
I think the issue is with your <%= form_for .. %> I can get the same error if I enter an invalid argument for that. For the school one try <%= form_for #school %> And make sure your new method in your controller (whichever one is rendering the page with the form) is making a new instance of the object,
def new
#school = School.new
end
And the same with the pin
Something like this may be what you're looking for
before_action :check_code, only: :create
...
def check_code
unless School.find_by school_code params[:school_code]
flash[:error] = "Invalid school code"
redirect_to new_reg_path
end
end
And to show the flash message
<% flash.each do |message_type, message| %>
<div class="alert alert-<%= message_type %>">
<%= message %>
</div>
<% end %>
I am using a Wrapbootstrap downloaded template, with devise for user registration and log in but am not getting any errors to pop up.
In all my views for devise I am calling <%= devise_error_messages! %>
In my model the following validations:
validates :first_name, presence: true
validates :last_name, presence: true
validates :phone_number, presence: true
Here is my Devise_helper.rb
module DeviseHelper
def devise_error_messages!
return '' if resource.errors.empty?
messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join
html = <<-HTML
<div class="alert alert-error alert-block"> <button type="button"
class="close" data-dismiss="alert">x</button>
#{messages}
</div>
HTML
html.html_safe
end
end
Here is my Registration New view page:
<!--=== Content Part ===-->
<div class="container content">
<div class="row">
<div class="col-md-6 col-md-offset-3 col-sm-8 col-sm-offset-2">
<form class="reg-page">
<div class="reg-header">
<h2>Register a new account</h2>
<p>Already Signed Up? Click <%= link_to "Sign In", login_url %> to login your account.</p>
</div>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<label>First Name<span class="color-red">*</span></label>
<%= f.text_field :first_name, autofocus: true, :class=> "form-control margin-bottom-20" %>
<label>Last Name<span class="color-red">*</span></label>
<%= f.text_field :last_name, autofocus: true, :class=> "form-control margin-bottom-20" %>
<label>Phone Number<span class="color-red">*</span></label>
<%= f.text_field :phone_number, autofocus: true, :class=> "form-control margin-bottom-20" %>
<label>Email Address <span class="color-red">*</span></label>
<%= f.email_field :email, autofocus: true, :class=> "form-control margin-bottom-20" %>
<div class="row">
<div class="col-sm-6">
<label>Password <span class="color-red">*</span></label>
<% if #validatable %>
<em>(<%= #minimum_password_length %> characters minimum)</em>
<% end %>
<%= f.password_field :password, autocomplete: "off", :class=> "form-control margin-bottom-20" %>
</div>
<div class="col-sm-6">
<label>Confirm Password <span class="color-red">*</span></label>
<%= f.password_field :password_confirmation, autocomplete: "off",:class=> "form-control margin-bottom-20" %>
</div>
</div>
<hr>
<div class="row">
<div class="col-lg-6 text-right">
<%= f.submit "Sign up", :class=> "btn-u" %>
</div>
</div>
</form>
</div>
</div>
<% end %>
</div><!--/container-->
<!--=== End Content Part ===-->
And when I submit an uncomplete form a query string like this is generated: http://localhost:3000/login?utf8=%E2%9C%93&authenticity_token=v%2BKndd3om3fBChpsZ6riw%2FVBiVM1ehVbKgBF9tIlg6PB6p30oei7OU3toqthjU1TY67yI3gmzjigxGe5DWfX7w%3D%3D&user%5Bemail%5D=&user%5Bpassword%5D=fwf&user%5Bremember_me%5D=0&commit=Log+in
Try with this in your helper file:
message_html << "<div class="alert alert-error alert-block"> <button type="button" class="close" data-dismiss="alert">x</button>"
message_html.html_safe
Also, check for flash message in your layout page or corresponding login page as:
<% if flash[:alert] %>
<span class='flash_error'> <%= flash[:alert] %></span>
<% end %>
There reason for this was because the template I was using had its own Javascript for error messages that was overriding the error messages of devise. Both error messages were not showing up until I removed the JS included in the Wrapbootstrap template and it works now
I'm trying to edit using a form <%= form_for #agent, :action => 'agents/update', :method => :put do |f| %> but when I click on Save Changes the form is submitted as a GET request instead of a PUT to the update action.
I have resources :agents in my routes.rb file.
In agents_controller.rb the show and update actions are:
def show
#agent = Agent.find(params[:id])
#subscription = #agent.subscription
end
def edit
#agent = Agent.find(params[:id])
#subscription = #agent.subscription
end
def update
#agent = Agent.find(params[:id])
#subscription = #agent.subscription
#agent.update_attributes(:agent)
end
It's pretty depressing when you can't get a standard edit form working, any help appreciated.
EDIT
agents/edit.html.erb
<%= form_for #agent do |f| %>
<ul>
<% for message in #agent.errors.full_messages %>
<li><%= message %></li>
<% end %>
</ul>
<div class="control-group">
<label class="control-label" style="width:200px;margin-right:20px"><strong>First name</strong></label>
<div class="controls">
<%= f.text_field :first_name, :placeholder => 'First name', :class => '', :style => '' %>
</div>
</div>
<div class="control-group">
<label class="control-label" style="width:200px;margin-right:20px"><strong>Last name</strong></label>
<div class="controls">
<%= f.text_field :last_name, :placeholder => 'Last name', :class => '', :style => '' %>
</div>
</div>
<div class="control-group">
<label class="control-label" style="width:200px;margin-right:20px"><strong>Email</strong></label>
<div class="controls">
<%= f.text_field :email, :placeholder => 'Your email', :class => '', :style => '' %>
</div>
</div>
<div class="control-group">
<label class="control-label" style="width:200px;margin-right:20px"><strong>Phone</strong></label>
<div class="controls">
<%= f.text_field :phone, :placeholder => 'Your phone number', :class => '', :style => '' %>
</div>
</div>
<div class="form-actions">
<%= f.submit "Save Changes", :class => 'btn btn-success' %>
<%= link_to 'Cancel', leads_path, :class => 'btn' %>
</div>
<% end %>
You shouldn't need to supply a method nor an action for a simple form like this. A simple
<% form_for #agent do |f| %>
should do you. Have you tried that? Are there any other forms on the page that could be conflicting? If so, try removing those other forms first, then see how that goes.
Fixed it. This post covered the exact same issue: HTML <form> tag causing Rails form to submit a GET instead of POST request
The GET request is being caused by a form tag around the rails form which was there to add the twitter bootstrap styling class "form-horizontal". Removed the extra form tag and it works fine.