1

I am new to Ruby and Rails and I am setting up authentication using Devise gem. I am receiving the below error when I try to sign up a new account.

TRANSACTION (0.2ms) BEGIN User Exists? (0.5ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2 [["email", "test@test.com"], ["LIMIT", 1]] TRANSACTION (0.2ms) ROLLBACK

I am unable to understand why I am getting this error. I have no users in the User table. I have deleted all the existing users.

Below is the User model

class User < ApplicationRecord

  belongs_to :department
  belongs_to :jobrole
  belongs_to :empappraisalrating
  belongs_to :empcategory
  belongs_to :empofficelocation
  belongs_to :empwork
  belongs_to :empworkshift
  belongs_to :gender
  belongs_to :companyname
  belongs_to :empsocialstatus
  ############################################################################################
  ## PeterGate Roles                                                                        ##
  ## The :user role is added by default and shouldn't be included in this list.             ##
  ## The :root_admin can access any page regardless of access settings. Use with caution!   ##
  ## The multiple option can be set to true if you need users to have multiple roles.       ##
  petergate(roles: [:admin, :employee, :hr, :companypresident, :approver, :manager, :supervisor, :externalclient], multiple: false)                                      ##
  ############################################################################################ 
 

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable




  #Method to search employees
  def self.search_employee(employee_name)
    
    if employee_name.nil?
      User.all
    else
      User.where(name: employee_name)
    end
  end


  #Method to Import employees into the software.
  #Uses inbuilt Ruby CSV library. 
  def self.import(file)
     CSV.foreach(file.path, headers:true) do |row|
       User.create! row.to_hash
     end
  end

  
  #Method to Export employees into the software.
  #Uses inbuilt Ruby CSV library.
  def self.to_csv
    CSV.generate do |csv|
      csv << column_names
        User.all.each do |employee|
          csv << employee.attributes.values_at(*column_names)
        end
    end
  end

  #Method to archive existing employee.
  def self.archive_employee(employeeid)
    employeeIdentity = employeeid
    employeetobearchived = User.find(employeeIdentity)
    employeetobearchived.estatus = "true"
    employeetobearchived.save
  end

end

Below are the details when I run User.all in Rails console. You can see its nil.

Loading development environment (Rails 7.0.6)
irb(main):001:0> User.all
  User Load (22.7ms)  SELECT "users".* FROM "users"
=> []
irb(main):002:0>

Can you please help me understand what wrong am I doing wrong ?

I was expecting a new user to be created.

I have no users in the User table. I have deleted all the existing users.

Form:

<div class = "container">


<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<div class = "container">
  
    <div class = "row">

        <p class="display-6">ACCOUNT INFORMATION</p>
                 <div class="form-group col-6">
                  <b>USERNAME:</b>
                 <%= f.email_field :email, placeholder: "Enter username", class: 'form-content form-content w-100 p-1' %>
                 </div>

                 <div class="form-group col-6">
                 <b>DEFAULT PASSWORD</b>
                 <%= f.password_field :password, placeholder: "Enter password (Minimum length: 6 characters)", class: 'form-content form-content w-100 p-1' %>
                 </div>
    </div>

    <div class = "row">
                <div class="form-group col-6">
                <b>CONFIRM DEFAULT PASSWORD:</b>
                <%= f.password_field :password_confirmation, placeholder: "Re-enter password to confirm", class: 'form-content form-content w-100 p-1' %>
                </div>

                <div class="form-group col-6">
                <b>ROLE:</b>
                <%= f.text_field :role, class: 'form-content form-content w-100 p-1' %>
                </div>
    </div>
    <hr/>
  
    <div class = "row">
          <p class="display-6">BASIC DETAILS</p>
                 <div class="form-group col-6">
                 <b>NAME:</b>
                 <%= f.text_field :name, placeholder: 'Enter employee name', class: 'form-content form-content w-100 p-1'%>
                 </div>

                 <div class="form-group col-6">
                 <b>DEPARTMENT:</b>
                 <%= select_tag(:department, options_from_collection_for_select(Department.all, :id, :name), include_blank: "Select department", class: 'form-content form-content w-100 p-1') %>
                 </div>

    </div>

    <div class="row">
  

                 <div class="form-group col-6">
                 <b>JOB ROLE:</b>
                 <%= select_tag(:post, options_from_collection_for_select(Jobrole.all, :id, :name), include_blank: "Select employee's current designation", class: 'form-content form-content w-100 p-1') %>                 
                </div>

                 <div class="form-group col-6">
                 <b>REPORTS TO:</b>
                 <%= select_tag(:manager, options_from_collection_for_select(User.all, :id, :name), include_blank: "Select employee's direct manager", class: 'form-content form-content w-100 p-1') %>
                 </div>

    </div>

    <div class="row">
  

                <div class="form-group col-6">
                <b>EMPLOYEE NUMBER:</b>
                <%= f.number_field :empnumber, :size => 80, class: 'form-content w-100 p-1' %>
                </div>

 
                <div class="form-group col-6">
                <b>EMPLOYEE TYPE:</b>
               <%= select_tag(:empcategory, options_from_collection_for_select(Empcategory.all, :id, :name), include_blank: "Select Employee Category", class: 'form-content form-content w-100 p-1') %>
                </div>
  
    </div>

    <div class="row">
  

               <div class="form-group col-6">
               <b>OFFICE LOCATION:</b>
              <%= select_tag(:officelocation, options_from_collection_for_select(Empofficelocation.all, :id, :name), include_blank: "Select employee's current office location", class: 'form-content form-content w-100 p-1') %>
               </div>

               <div class="form-group col-6">
               <b>WORK PREFERENCE:</b>
               <%= select_tag(:workstyle, options_from_collection_for_select(Empwork.all, :id, :name), include_blank: "Select employee's working preference", class: 'form-content form-content w-100 p-1') %>
               </div>

    </div>

    <div class="row">
  

              <div class="form-group col-6">
              <b>GENDER:</b>
              <%= select_tag(:gender, options_from_collection_for_select(Gender.all, :id, :name), include_blank: "Select employee's gender", class: 'form-content form-content w-100 p-1') %>
              </div>

              <div class="form-group col-6">
              <b>COMPANY NAME:</b>
             <%= select_tag(:companyname, options_from_collection_for_select(Companyname.all, :id, :name), include_blank: "Select Company name", class: 'form-content form-content w-100 p-1') %>
              </div>

    </div>


    <div class="row">
  

              <div class="form-group col-6">
              <b>START DATE:</b>
              <%= f.date_field :employedon, :size => 80, class: 'form-content w-100 p-1' %>
              </div>

              <div class="form-group col-6">
              <b>WORK SHIFT:</b>
              <%= select_tag(:workshift, options_from_collection_for_select(Empworkshift.all, :id, :name), include_blank: "Select employee's working hours", class: 'form-content form-content w-100 p-1') %>
              </div>

    </div>

    <hr/>


         <p class="display-6">EMPLOYEE PERSONAL DETAILS</p>


  
             <div class="form-group">
             <b>PERMANENT ADDRESS:</b>
             <%= f.text_area :address, class: 'form-content form-content w-100 p-3' %>
             </div>

    <div class="row">

             <div class="form-group col-6">
             <b>DATE OF BIRTH:</b>
             <%= f.date_field :DOB, class: 'form-content form-content w-100 p-1' %>
             </div>

  
             <div class="form-group col-6">
             <b>LANDLINE/MOBILE:</b>
             <%= f.number_field :contact, class: 'form-content form-content w-100 p-1' %>
             </div>

    </div>

             <div class="form-group">
             <b>PERSONAL EMAIL ADDRESS:</b>
             <%= f.email_field :personalemail, class: 'form-content form-content w-100 p-1' %>
             </div>

             <div class="form-group">
             <b>SOCIAL STATUS:</b>
             <%= select_tag(:socialstatus, options_from_collection_for_select(Empsocialstatus.all, :id, :name), include_blank: "Select employee's social status", class: 'form-content form-content w-100 p-1') %>
             </div>


    <hr/>


          <p class="display-6">EMPLOYEE MEDICAL RECORDS</p>

   
            <div class="form-group">
            <b>DECLARED PERMANENT ILLNESS (IF ANY):</b>
            <%= f.text_area :employeepermanentillness, class: 'form-content form-content w-100 p-1' %>
            </div>

            <div class="form-group">
            <b>PHYSICALLY HANDICAPPED:</b>
            <%= f.text_field :phstatus, class: 'form-content form-content w-100 p-1' %>
            </div>
  

    <hr/>


        <p class="display-6">COMPENSATION DETAILS</p>

            
    <div class="row">
            
           <div class="form-group col-6">
           <b>BASIC PAY:</b>
           <%= f.number_field :bpay, class: 'form-content w-100 p-1' %>
           </div>

           <div class="form-group col-6">
           <b>ANNUAL CTC</b>
           <%= f.number_field :ctc, class: 'form-content form-content w-100 p-1' %>
           </div>

    </div>

    <div class="row">
          

          <div class="form-group col-6">
          <b>SALARY LAST REVISION:</b>
          <%= f.date_field :lastrevision, class: 'form-content w-100 p-1' %>
          </div>

          <div class="form-group col-6">
          <b>LATEST APPRAISAL RATING:</b>
          <%= select_tag(:appraisalrating, options_from_collection_for_select(Empappraisalrating.all, :id, :name), include_blank: "Select employee's last appraisal rating", class: 'form-content form-content w-100 p-1') %>
          </div>

  </div>
  
          <div class="form-group">
          <b>LATEST APPRAISAL COMMENTS</b>
          <%= f.text_area :appraisalcomments, class: 'form-content form-content w-100 p-3' %>
          </div>
  
  <hr/>



        <p class="display-6">OTHER DETAILS</p>

  <div class="row">
  
          <div class="form-group col-6">
          <b>OTHER SUPERVISORS - 1</b>
          <%= f.text_field :sup1, class: 'form-content w-100 p-1' %>
          </div>

          <div class="form-group col-6">
          <b>OTHER SUPERVISORS - 2</b>
          <%= f.text_field :sup2, class: 'form-content form-content w-100 p-1' %>
         </div>
 </div>

 <div class="row">
  
          <div class="form-group col-6">
          <b>OTHER SUPERVISORS - 3</b>
          <%= f.text_field :sup3, class: 'form-content w-100 p-1' %>
          </div>

          <div class="form-group col-6">
          <b>OTHER SUPERVISORS - 4</b>
          <%= f.text_field :sup4, class: 'form-content form-content w-100 p-1' %>
         </div>
 </div>
 
  <hr/>

  <div class="actions">
     <%= f.submit 'CREATE RECORD', class: 'btn btn-sm btn-block btn-secondary rounded-0' %>
  </div>

<% end %>

</div

User Table Schema

  create_table "users", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "roles"
    t.string "name"
    t.string "department"
    t.date "employedon"
    t.string "manager"
    t.integer "appraisalrating"
    t.bigint "ctc"
    t.string "empcategory"
    t.integer "empnumber"
    t.string "post"
    t.date "DOB"
    t.string "personalemail"
    t.bigint "contact"
    t.string "officelocation"
    t.string "workstyle"
    t.string "gender"
    t.string "companyname"
    t.string "workshift"
    t.text "address"
    t.string "socialstatus"
    t.text "employeepermanentillness"
    t.string "phstatus"
    t.bigint "bpay"
    t.date "lastrevision"
    t.text "appraisalcomments"
    t.string "sup1"
    t.string "sup2"
    t.string "skillcategory"
    t.boolean "estatus"
    t.string "role"
    t.string "sup3"
    t.string "sup4"
    t.bigint "department_id"
    t.bigint "jobrole_id"
    t.bigint "empcategory_id"
    t.bigint "empwork_id"
    t.bigint "empworkshift_id"
    t.bigint "companyname_id"
    t.bigint "empofficelocation_id"
    t.bigint "gender_id"
    t.bigint "empsocialstatus_id"
    t.bigint "empappraisalrating_id"
    t.index ["companyname_id"], name: "index_users_on_companyname_id"
    t.index ["department_id"], name: "index_users_on_department_id"
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["empappraisalrating_id"], name: "index_users_on_empappraisalrating_id"
    t.index ["empcategory_id"], name: "index_users_on_empcategory_id"
    t.index ["empofficelocation_id"], name: "index_users_on_empofficelocation_id"
    t.index ["empsocialstatus_id"], name: "index_users_on_empsocialstatus_id"
    t.index ["empwork_id"], name: "index_users_on_empwork_id"
    t.index ["empworkshift_id"], name: "index_users_on_empworkshift_id"
    t.index ["gender_id"], name: "index_users_on_gender_id"
    t.index ["jobrole_id"], name: "index_users_on_jobrole_id"
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  end

Server

Started POST "/users" for ::1 at 2023-08-02 20:26:38 +0530
Processing by Devise::RegistrationsController#create as TURBO_STREAM
  Parameters: {"authenticity_token"=>"[FILTERED]", "user"=>{"email"=>"test@gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "role"=>"user", "name"=>"", "empnumber"=>"", "employedon"=>"", "address"=>"Flat 601, Block A, Umiya Habitat\nZuarinagar", "DOB"=>"", "contact"=>"", "personalemail"=>"", "employeepermanentillness"=>"", "phstatus"=>"", "bpay"=>"", "ctc"=>"", "lastrevision"=>"", "appraisalcomments"=>"", "sup1"=>"", "sup2"=>"", "sup3"=>"", "sup4"=>""}, "department"=>"", "post"=>"", "manager"=>"", "empcategory"=>"", "officelocation"=>"", "workstyle"=>"", "gender"=>"", "companyname"=>"", "workshift"=>"", "socialstatus"=>"", "appraisalrating"=>"", "commit"=>"CREATE RECORD"}
  TRANSACTION (0.8ms)  BEGIN
  User Exists? (0.7ms)  SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2  [["email", "test@gmail.com"], ["LIMIT", 1]]
  TRANSACTION (0.5ms)  ROLLBACK
  Rendering layout layouts/application.html.erb
  Rendering devise/registrations/new.html.erb within layouts/application
  Department Load (0.4ms)  SELECT "departments".* FROM "departments"
  ↳ app/views/devise/registrations/new.html.erb:43
  Jobrole Load (0.4ms)  SELECT "jobroles".* FROM "jobroles"
  ↳ app/views/devise/registrations/new.html.erb:53
  User Load (0.7ms)  SELECT "users".* FROM "users"
  ↳ app/views/devise/registrations/new.html.erb:58
  Empcategory Load (0.6ms)  SELECT "empcategories".* FROM "empcategories"
  ↳ app/views/devise/registrations/new.html.erb:74
  Empofficelocation Load (0.5ms)  SELECT "empofficelocations".* FROM "empofficelocations"
  ↳ app/views/devise/registrations/new.html.erb:84
  Empwork Load (0.5ms)  SELECT "empworks".* FROM "empworks"
  ↳ app/views/devise/registrations/new.html.erb:89
  Gender Load (0.4ms)  SELECT "genders".* FROM "genders"
  ↳ app/views/devise/registrations/new.html.erb:99
  Companyname Load (0.6ms)  SELECT "companynames".* FROM "companynames"
  ↳ app/views/devise/registrations/new.html.erb:104
  Empworkshift Load (1.5ms)  SELECT "empworkshifts".* FROM "empworkshifts"
  ↳ app/views/devise/registrations/new.html.erb:120
  Empsocialstatus Load (0.4ms)  SELECT "empsocialstatuses".* FROM "empsocialstatuses"
  ↳ app/views/devise/registrations/new.html.erb:159
  Empappraisalrating Load (0.3ms)  SELECT "empappraisalratings".* FROM "empappraisalratings"
  ↳ app/views/devise/registrations/new.html.erb:210
  Rendered devise/registrations/new.html.erb within layouts/application (Duration: 41.0ms | Allocations: 12537)
  Rendered layout layouts/application.html.erb (Duration: 138.0ms | Allocations: 18866)
Completed 422 Unprocessable Entity in 801ms (Views: 133.3ms | ActiveRecord: 8.4ms | Allocations: 24436)

Routes

devise_for :users
  • Add the code you are using to create a new user to the question. – dbugger Aug 02 '23 at 14:15
  • Hi @dbugger Do you mean the form? I have added form and User table Schema to the question. Also, I have not overridden Devise Registrations controller. – TEJINDER SINGH Aug 02 '23 at 14:37
  • Is there any more to the error indicating WHY the transaction was rolled back? – dbugger Aug 02 '23 at 14:50
  • @dbugger No. However, I have attached the full message I am receiving on the server. I have no validations added up to the User model. I can also see that parameters have been captured and just when the POST action is underway ...a rollback happens. It's kind of strange. Let me know if you require any other details. Thanks for your help on this. – TEJINDER SINGH Aug 02 '23 at 15:01
  • Looking at this https://stackoverflow.com/questions/16204286/rails-devise-user-exists-on-empty-db the issue isn't the empty db, it's that the user you are trying to create isn't valid. See if you can create it in the console. – dbugger Aug 02 '23 at 15:18
  • The "error message" you posted is not an error message, it's a database query that contains no information about what the actual error is. You should be seeing *some* output in your browser, or in your network traffic in your browser's developer tools. At worse, you may have to use `binding.pry` to step in to the controller and inspect the errors returned by calling `errors` on your model. – user229044 Aug 02 '23 at 19:41

1 Answers1

1

I think it was Rails5 which made belongs_to mandatory by default, so your user is failing to save because of validation errors on all those missing associations.

  1. You can add optional: true to any/all of them that are not meant to be mandatory, and
  2. You really should be pushing the errors for a failed validation back to your frontend for many reasons, devs not being surprised by failures being an important one.
smathy
  • 26,283
  • 5
  • 48
  • 68