I have a simple Ruby on Rails app, with Devise for authentication. I would like to have users log in using a username instead of email, and attempted to implement this as described here: Devise authenticating with username instead of email
The twist is that I still want each User to have an email address, and require one during sign-up. So, I left the 'email' field on the sign-up form.
The problem is, when I fill out the sign-up form using a valid email address (or any other value for email), Devise gives an error: "Email can't be blank".
Why is the email being treated as blank, and how can I fix it?
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :password, :password_confirmation, :remember_me) }
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :password, :remember_me) }
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:username, :email, :password, :password_confirmation, :current_password) }
end
end
User model
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
View for the sign-up
<h2>Sign up</h2>
<%= 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 :username %><br />
<%= f.text_field :username %>
</div>
<div class="field">
<%= f.label :password %>
<% if @validatable %>
<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>
<div class="actions">
<%= f.submit "Sign up" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
devise.rb modified to include:
config.authentication_keys = [ :username ]
This is output in the rails server console when the form is submitted:
Started POST "/users" for ::1 at 2015-03-17 14:29:13 -0700
Processing by Devise::RegistrationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"bc5+ffyBSr6h79aumdMpwHhp5OY69
Tk5oKyY+eIBHLCDDwPmxiMbjbE6OTIaeUPGLmS0J+QlwlGFGHki8SKsgA==", "user"=>{"email"=>
"[email protected]", "username"=>"Jessa", "password"=>"[FILTERED]", "password_co
nfirmation"=>"[FILTERED]"}, "commit"=>"Sign up"}
Unpermitted parameter: email
(0.0ms) BEGIN
(0.0ms) ROLLBACK
Rendered devise/shared/_links.html.erb (2.0ms)
Rendered devise/registrations/new.html.erb within layouts/application (11.0ms)
I can see Unpermitted parameter: email
, but am not sure how to fix it.
The code in question is correct, and works. It can used as a working example of devise log-ins using a username, though there are plenty of tutorials that cover this.
The error was a stupid mistake: a file was accidentally in the wrong place. Thanks goes to Evgeny Petrov, who's example provided in the comments helped me to track down the discrepancy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With