Techioz Blog

Ruby on Rails 認証: Devise サインアップが機能しない [終了]

概要

私は Ruby と Rails を初めて使用しており、Devise gem を使用して認証を設定しています。新しいアカウントにサインアップしようとすると、次のエラーが表示されます。

トランザクション (0.2ms) BEGIN ユーザーは存在しますか? (0.5ミリ秒) SELECT 1 AS one FROM “users” WHERE “users”.”email” = LIMIT [[“email”, “[email protected]”], [“LIMIT”, 1]] TRANSACTION (0.2ミリ秒) ROLLBACK

なぜこのエラーが発生するのか理解できません。 User テーブルにはユーザーがいません。既存のユーザーをすべて削除しました。

以下はユーザーモデルです

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

以下は、Rails コンソールで User.all を実行したときの詳細です。ゼロであることがわかります。

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>

私が間違っていることを理解するのを手伝ってもらえますか?

新しいユーザーが作成されることを期待していました。

User テーブルにはユーザーがいません。既存のユーザーをすべて削除しました。

形状:

<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

ユーザーテーブルスキーマ

  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

サーバ

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"=>"[email protected]", "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", "[email protected]"], ["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)

ルート

devise_for :users

解決策

デフォルトでbelongs_toを必須にしたのはRails5だったと思います。そのため、ユーザーは、欠落している関連付けすべてで検証エラーが発生して保存に失敗しています。