Benjamints Benjamints - 8 days ago 5
Ruby Question

Implementing usernames to devise

I have followed the documentation online, however I am still struggling and I don't know where I went wrong. When I am trying to sign a user up, all I am seeing is 'please review the problems below' upon them submitting, which isn't even being displayed.The terminal also isn't saying much.

Application Controller:

class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :authenticate_user!
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: [:username, :password]
devise_parameter_sanitizer.permit :account_update, keys: [:username, :password]
end


end


User model:

class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
has_many :stories
validates :username, :presence => true, :uniqueness => { :case_sensitive => false}
validates_format_of :username, with: /^[a-zA-Z0-9_\.]*$/, :multiline => true
attr_accessor :login
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :authentication_keys => {email: true, login: false}

def self.find_for_database_authentication(warden_conditions)
conditions = warden_conditions.dup
if login = conditions.delete(:login)
where(conditions.to_h).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first
elsif conditions.has_key?(:username) || conditions.has_key?(:email)
where(conditions.to_h).first
end
end

end


In the terminal:

Processing by Devise::RegistrationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"sTFYfOW5txc1AYinMyWDdaMfggAGh1oX/JSrR7vXc25cEwW5krezOQ6V5zE6QLXI6Dmwi8X3LN8s91rahJBxww==", "user"=>{"username"=>"indigo", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up"}
(0.1ms) begin transaction
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."username") = LOWER(?) LIMIT ? [["username", "indigo"], ["LIMIT", 1]]
(0.1ms) rollback transaction
Rendering users/registrations/new.html.erb within layouts/application
Rendered users/shared/_links.html.erb (1.3ms)
Rendered users/registrations/new.html.erb within layouts/application (8.7ms)
/home/benjamin/Desktop/projectoxygen/app/views/layouts/application.html.erb:47: warning: else without rescue is useless
Completed 200 OK in 306ms (Views: 42.4ms | ActiveRecord: 0.4ms)


devise db file:

class DeviseCreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
## Database authenticatable
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""

## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at

## Rememberable
t.datetime :remember_created_at

## Trackable
t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip

## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable

## Lockable
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at


t.timestamps null: false
end

add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true

change_column :users, :email, uniqueness: false

# add_index :users, :confirmation_token, unique: true
# add_index :users, :unlock_token, unique: true
end
end


current errors:

ActiveRecord::RecordNotUnique in Devise::RegistrationsController#create
SQLite3::ConstraintException: UNIQUE constraint failed: users.email: INSERT INTO "users" ("encrypted_password", "created_at", "updated_at", "username") VALUES (?, ?, ?, ?)


terminal:

ActiveRecord::RecordNotUnique in Devise::RegistrationsController#create
SQLite3::ConstraintException: UNIQUE constraint failed: users.email: INSERT INTO "users" ("encrypted_password", "created_at", "updated_at", "username") VALUES (?, ?, ?, ?)

dkp dkp
Answer

If you are using username instead of email as authentication key, then you must have defined:

#config/initializers/devise.rb
config.authentication_keys = [:username]

- OR, you can define authentication key in model also as:

devise :database_authenticatable, :authentication_keys => [:username]

Add the following methods to model User in order to avoid validations for email:

def email_required?
  false
end

def email_changed?
  false
end

If you have a UNIQUE constraint over the email column, then create a migration to remove index on email column:

def change
  remove_index :users, :email
end