validates_confirmation_of :password does not work when I submitted my form. Even if the password confirmation is not the same, the user is signed up.
I wrote the same thing that the guide. during my research , I did not found anything that explain that.
Do you know what is happening and how can I solve it?
Here is my code:
My view:
<%= form_for User.new do |f| %>
<div class="row">
<div class="col-md-6">
<%= f.label :Prénom %> :
<%= f.text_field :first_name, class: "form-control" %><br />
</div>
<div class="col-md-6">
<%= f.label :Nom %> :
<%= f.text_field :last_name, class: "form-control" %><br />
</div>
</div>
<div class="row">
<div class="col-md-6">
<%= f.label :Pseudo %> :
<%= f.text_field :user_name, class: "form-control"%><br />
</div>
<div class="col-md-6">
<%= f.label :Email %> :
<%= f.email_field :email, class: "form-control" %><br />
</div>
</div>
<div class="row">
<div class="col-md-6">
<%= f.label :Mot_de_passe %> :
<%= f.password_field :password, class: "form-control" %><br />
</div>
<div class="col-md-6">
<%= f.label :Confirmation_mot_de_passe %> :
<%= f.password_field :password_confirmation, class: "form-control" %><br />
</div>
</div>
<%= f.label :Club_favori %> :
<%=f.select(:club) do%>
<%= options_from_collection_for_select(Club.all,:id ,:name) %>
<% end %>
<br>
<%= f.submit class: "btn btn-primary" %>
<% end %>
My model:
class User < ActiveRecord::Base
has_merit
has_secure_password
has_many :comments
validates_length_of :password, minimum: 5, too_short: 'please enter at least 5 characters', on: :create
validates_presence_of :user_name, :message => 'Vous devez remplir tout les champs.', on: :create
validates_uniqueness_of :user_name, :case_sensitive => false, :message => "Ce pseudo n'est pas disponible.", on: :create
validates_confirmation_of :password, on: :create
end
My controller:
class UsersController < ApplicationController
def create
#user = User.new(user_params)
if #user.save
#user.add_badge(1)
session[:user_id] = #user.id
redirect_to '/feed'
else
redirect_to '/signup', flash: {error_message: #user.errors}
end
end
private
def user_params
params.require(:user).permit( :user_name, :first_name, :last_name, :email, :password, :sash, :club)
end
def new
#user = User.new
#clubs =Club.all
end
end
Thank you in advance for your help.
You override your current #user when you enter your form.
Just change:
<%= form_for User.new do |f| %>
to
<%= form_for #user do |f| %>
Related
I need to add Address nested attributes for User.
But only user_id hits the addresses table when I submit, and not country city street and zip_code
user.rb
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
validates_presence_of :name, :age, :email
has_one :address, dependent: :destroy
accepts_nested_attributes_for :address
address.rb
attr_accessor :country, :city, :zip_code, :street
belongs_to :user
appication_controller.rb
before_action :configure_permitted_parameters, if: :devise_controller?
...
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :age,
address_attributes: [:country, :city, :zip_code, :street]])
end
The form
<% resource.build_address %>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<div class="form-group">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email", class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :name %><br />
<%= f.text_field :name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :age %><br />
<%= f.number_field :age, class: 'form-control' %>
</div>
<h4>Address</h4>
<%= f.fields_for :address do |address| %>
<div class="form-group">
<%= address.label :country %>
<%= address.text_field :country, class: 'form-control' %>
</div>
<div class="form-group">
<%= address.label :city %>
<%= address.text_field :city, class: 'form-control'%>
</div>
<div class="form-group">
<%= address.label :street %>
<%= address.text_field :street, class: 'form-control'%>
</div>
<div class="form-group">
<%= address.label :zip_code %>
<%= address.text_field :zip_code, class: 'form-control' %>
</div>
<% end %>
<div class="form-group">
<%= f.label :password %>
<% if #minimum_password_length %>
<em>(<%= #minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "new-password", class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password", class: 'form-control' %>
</div>
<div class="form-group">
<%= f.submit "Sign up", class: 'btn btn-success' %>
</div>
<% end %>
I'm new to rails and trying to create a profile for devise users when they signup, using nested form in devise signup. I've gone through
Creating Profile for Devise users,
Profile model for Devise users?
and few other articles to achieve the same but after a day in vain, I'm still trying to make it work. Here is my code.
Model - user.rb
class User < ActiveRecord::Base
has_one :user_profile
accepts_nested_attributes_for :user_profile
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
Model - user_profile.rb
class UserProfile < ActiveRecord::Base
belongs_to :user
end
Controller - controllers/users/registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) {|u|
u.permit(:email, :password, :password_confirmation, :remember_me,
user_profile_attributes: [:first_name, :last_name])}
end
end
end
View - views/devise/registrations/new.html.erb
<h2>Sign up</h2>
<% resource.build_user_profile %>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
<%= f.label :password %>
<% if #minimum_password_length %>
<em>(<%= #minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<%= f.fields_for :user_profile do |profile_form| %>
<%= profile_form.label :first_name %><br/>
<%= profile_form.text_field :first_name %><br/>
<%= profile_form.label :last_name %><br/>
<p><%= profile_form.text_field :last_name %><br/>
<% end %>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
Server Log
Processing by Devise::RegistrationsController#create as HTML
Parameters: {"utf8"=>"√", "authenticity_token"=>"rLuFXwISxiJpWPjpmKzjnjhKr41F5
56sWbtT+8gslAMsFDWRbl7MSitSXUESjLdZccCBGBGvVv+JbhW7G5py5g==", "user"=>{"email"=>
"zebandz#gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTER
ED]", "user_profile_attributes"=>{"first_name"=>"Zeban", "last_name"=>"Dezend"}}
, "commit"=>"Sign up"}
Unpermitted parameter: user_profile_attributes
I think, I'm missing the code to fetch the values from params and create a new record. Can someone suggest me the fix ?
please follow the below steps.
devise> reg > new
<div class="row">
<div class="col-md-5 col-md-offset-4">
<h2>Sign up</h2>
<% resource.build_user_profile if resource.user_profile.nil? %>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="row">
<%= f.fields_for :user_profile do |profile_form| %>
<div class="col-md-6">
<div class="form-group">
<%= profile_form.label :first_name %>
<%= profile_form.text_field :first_name, class: "form-control" %>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<%= profile_form.label :last_name %>
<%= profile_form.text_field :last_name, class: "form-control" %>
</div>
</div>
<% end %>
</div>
<div class="form-group">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, class: "form-control" %>
</div>
<%= f.fields_for :user_profile do |profile_form| %>
<div class="form-group">
<%= profile_form.label :business_name %>
<%= profile_form.text_field :business_name, class: "form-control" %>
</div>
<div class="form-group">
<%= profile_form.label :business_category %>
<%= profile_form.collection_select :business_category_id, BusinessCategory.all, :id, :name, {prompt: "Select Category"}, {class: "form-control"} %>
</div>
<div class="form-group">
<%= profile_form.label :website %>
<%= profile_form.url_field :website, class: "form-control" %>
</div>
<div class="form-group">
<%= profile_form.label :address %>
<%= profile_form.text_area :address, class: "form-control" %>
</div>
<div class="form-group">
<%= profile_form.label :personal_number %>
<%= profile_form.text_field :phone_number, class: "form-control" %>
</div>
<div class="form-group">
<%= profile_form.label :office_number %>
<%= profile_form.text_field :office_number, class: "form-control" %>
</div>
<% end %>
<div class="form-group">
<%= f.label :password %>
<% if #minimum_password_length %>
<em>(<%= #minimum_password_length %> characters minimum)</em>
<% end %><br />
<%= f.password_field :password, autocomplete: "off", class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off", class: "form-control" %>
</div>
<div class="actions">
<%= f.submit "Sign up", class: "btn btn-primary" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
</div>
</div>
user reg controller
def new
# Override Devise default behaviour and create a profile as well
build_resource({})
resource.build_user_profile
respond_with self.resource
end
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up) { |u|
u.permit(:email, :password, :password_confirmation, :user_profile_attributes => [:first_name, :last_name, :business_name, :business_category_id, :website, :address, :phone_number, :office_number])
}
end
Have you tried following these steps from their github page?
They set the permitted parameters in the ApplicationController. Also the structure is a little different. The parameters go into keys.
https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
added_attrs = [:username, :email, :password, :password_confirmation, :remember_me]
devise_parameter_sanitizer.permit :sign_up, keys: added_attrs
devise_parameter_sanitizer.permit :account_update, keys: added_attrs
end
end
I'm learning rails and building an authentication system using guides from around the web and following railscasts tutorials.
I've come to a stand still at the moment and need a bit of assistance if possible.
When ever I try to edit the user profile, I get an error message which tells me that it can't create an account due to fields such as email and username already being taken.
Looking around it seems it's related to how my edit form is being submitted, but I can't solve it!
Any help would be appreciated.
Users_controller.rb
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
edit.html.erb
<%= form_for :user, url: '/users' do |f| %>
<form class="m-t" role="form" action="#">
<div class="form-group">
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control', autocomplete: "off" %>
</div>
<div class="form-group">
<%= f.label :user_type %>
<%= f.select(:user_type, ['Admin', 'Technical', 'Accounts'], {}, { :class => 'form-control' }) %>
</div>
<div class="form-group">
<%= f.label :email %>
<%= f.text_field :email, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :telephone %>
<%= f.text_field :telephone, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :mobile %>
<%= f.text_field :mobile, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :user_name %>
<%= f.text_field :user_name, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :company_admin%>
<%= f.check_box :company_admin, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :user_admin %>
<%= f.check_box :user_admin, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :emergency_contact %>
<%= f.check_box :emergency_contact, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.submit "Submit", class: "btn btn-primary block full-width m-b" %>
</div>
</form>
<% end %>
Rails Log
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = 'emailaddress#gmail.com' LIMIT 1
User Exists (0.1ms) SELECT 1 AS one FROM "users" WHERE "users"."user_name" = 'AUserName' LIMIT 1
user.rb
class User < ActiveRecord::Base
has_secure_password
validates :name, presence: { message: "Please enter your name." }
validates_uniqueness_of :email, presence: { message: "Please enter your email address." }
validates_format_of :email, with: /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z] {2,})\z/i, message: "Please enter a valid email address.", allow_blank: true
validates :telephone, presence: { message: "Please enter your phone number." }
validates :mobile, presence: { message: "Please enter your mobile number." }
validates_uniqueness_of :user_name, presence: { message: "Please enter your user name." }
validates_confirmation_of :password, presence: { message: "Please enter your password" }, allow_nil: true
before_create { generate_token(:auth_token) }
def generate_token(column)
begin
self[column] = SecureRandom.urlsafe_base64
end while User.exists?(column => self[column])
end
def send_password_reset
generate_token(:password_reset_token)
self.password_reset_sent_at = Time.zone.now
save!
UserMailer.password_reset(self).deliver
end
end
Wait I'm wrong on the validation. Just spotted it.
<%= form_for :user, url: '/users' do |f| %>
This won't use the #user object, which means rails thinks you're trying to create a user.
Switch it to
<%= form_for #user do |f| %>
Rails will also infer the correct place to post to so you won't need the url option anymore.
So i am trying to implement a dropdown menu in my edit form for users, i used devise, so this edit form is inside my devise/registrations/edit.html.erb file.
first i get and error for undefined method for :optionselect (which seems understandable since i couldn't find this elsewhere other than this select in form_for rails
so this is wrong.
<div class="field">
<%= f.label :role %><br />
<%= f.select :optionselect, User.options %>
</div>
i also had it like this
<div class="field">
<%= f.label :role %><br />
<%= f.select :role, [['Member', 'member'], ['Astronaut', 'astronaut'], ['Candidate', 'candidate']] %>
but no luck. because it wouldn't persist the changes i made when editing the role of the user.
Also the name doesn't persist when trying to update it. maybe that gives us a lead.
models/user.rb
class User < ActiveRecord::Base
has_many :books
has_many :reviews
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable,
:registerable,
:recoverable,
:rememberable,
:trackable,
:validatable
validates :email, presence: true, uniqueness: true
validates_format_of :email, :with => /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, :on => :create
validates :password,
:presence => { :on => :create },
:length => { :minimum => 6, :allow_nil => true }
OPTIONS = [
{:role => 'memeber'},
{:role => 'astronaut'},
{:role => 'candidate'}
]
def self.options
OPTIONS.map { |option| option[:role] }
end
end
controllers/users_controller.rb
class UsersController < ApplicationController
def index
binding.pry
#users = User.all
end
def show
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update!(user_params)
redirect_to :action => 'show', :id => #user
else
render :action => 'edit'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :role)
end
end
devise/registration/edit.html.erb
<h2>Edit <%= resource_name.to_s.humanize %></h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<%= devise_error_messages! %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name, autofocus: true %>
</div>
<div class="field">
<%= f.label :role %><br />
<%= f.select :optionselect, User.options %>
</div>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
<div class="field">
<%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off" %>
</div>
<div class="field">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password, autocomplete: "off" %>
</div>
<div class="actions">
<%= f.submit "Update" %>
</div>
<% end %>
<h3>Cancel my account</h3>
<p>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %></p>
<%= link_to "Back", :back %>
Let me know if you need more information
edit.html.erb
<%= f.select(:role, User::USER_OPTIONS) %>
models/user.rb
USER_OPTIONS = ["memeber", "astronaut", "candidate"]
When I submit the user update form, I don't get any errors, but the info doesn't update.
Here is my RegistrationsController
class RegistrationsController < Devise::RegistrationsController
private
def sign_up_params
params.require(:user).permit(:username, :email, :password, :password_confirmation, :firstname, :lastname, :displayname)
end
def account_update_params
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, :current_password)
end
end
Here is part of my routes.rb
devise_for :users, :controllers => { registrations: 'registrations' }
Finally here is the devise/registrations/edit.html.erb
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<%= render 'shared/error_messages' %>
<h1>Edit Your Profile</h1>
<div class="row">
<div class="col-md-4">
<h3>Social</h3>
<hr>
<div class="form-group">
<%= f.label :displayname, "Display Name" %><br>
<%= f.text_field :displayname, autocomplete: "off", class: "form-control" %>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-6">
<%= f.label :firstname, "First Name" %><br>
<%= f.text_field :firstname, class: "form-control" %>
</div>
<div class="col-md-6">
<%= f.label :lastname, "Last Name" %><br>
<%= f.text_field :lastname, class: "form-control" %>
</div>
</div>
</div>
<%= f.label :twitter, "Twitter" %><br>
<div class="input-group">
<div class="input-group-addon">twitter.com/</div>
<%= f.text_field :twitter, class: "form-control" %>
</div>
<br>
<%= f.label :facebook, "Facebook" %><br>
<div class="input-group">
<div class="input-group-addon">facebook.com/</div>
<%= f.text_field :facebook, class: "form-control" %>
</div>
<br>
<%= f.label :reddit, "Reddit" %><br>
<div class="input-group">
<div class="input-group-addon">reddit.com/u/</div>
<%= f.text_field :reddit, class: "form-control" %>
</div>
<br>
<%= f.label :github, "Github" %><br>
<div class="input-group">
<div class="input-group-addon">github.com/</div>
<%= f.text_field :github, class: "form-control" %>
</div>
<br>
<%= f.label :youtube, "Youtube" %><br>
<div class="input-group">
<div class="input-group-addon">youtube.com/user/</div>
<%= f.text_field :youtube, class: "form-control" %>
</div>
<br>
<%= f.label :twitch, "Twitch" %><br>
<div class="input-group">
<div class="input-group-addon">twitch.tv/</div>
<%= f.text_field :twitch, class: "form-control" %>
</div>
</div>
<div class="col-md-4">
<h3>Login Info</h3>
<hr>
<div class="form-group">
<%= f.label :email %><br>
<%= f.email_field :email, autofocus: true, class: "form-control" %>
</div>
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div class="alert alert-warning">Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>
<div class="form-group">
<%= f.label :password %><br>
<%= f.password_field :password, autocomplete: "off", class: "form-control" %>
<span class="help-block">Leave blank if you don't want to change it</span>
</div>
<div class="form-group"><%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation, autocomplete: "off", class: "form-control" %>
</div>
<div class="form-group"><%= f.label :current_password %>
<%= f.password_field :current_password, autocomplete: "off", class: "form-control" %></div>
<span class="help-block">Please enter your current password to confirm your changes</span>
</div>
<div class="col-md-4">
<h3>Your Stats</h3>
<hr>
</div>
</div>
<br>
<div class="form-group"><%= f.submit "Update", class: "btn btn-success" %></div>
<% end %>
<%= link_to "Back", :back %>
User Model:
class User < ActiveRecord::Base
rolify
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable, :timeoutable, :lockable
#ROLES = "%w[default plus moderator administrator suspended banned]"
# BEGIN HAS_MANYS
has_many :posts
has_many :assignments
has_many :evaluations, class_name: "RSEvaluation", as: :source
has_reputation :votes, source: {reputation: :votes, of: :posts}, aggregated_by: :sum
# BEGIN METHODS
def voted_for?(post)
evaluations.where(target_type: post.class, target_id: post.urlid).present?
end
# def has_role?(role_sym)
# roles.any? { |r| r.name.underscore.to_sym == role_sym }
# end
end
I have face same problem while updating user account with rails 4, but there is problem with parameter permitted .
Please update your controller like
class RegistrationsController < Devise::RegistrationsController
before_filter :update_sanitized_params, if: :devise_controller?
def update_sanitized_params
devise_parameter_sanitizer.for(:sign_up) {|u| u.permit(:username, :email, :password, :password_confirmation, :firstname, :lastname, :displayname)}
devise_parameter_sanitizer.for(:account_update) {|u| u.permit(:first_name, :last_name, :email, :password, :password_confirmation, :current_password)}
end
end
It will work :)