我正在实现一个设计合理的认证系统,但是在注册用户(在这种情况下为学生)时,将跳过以下错误:
ActiveRecord::NotNullViolation in Devise::RegistrationsController#create
SQLite3::ConstraintException: NOT NULL constraint failed: students.codigo: INSERT INTO "students" ("email", "encrypted_password", "created_at", "updated_at") VALUES (?, ?, ?, ?)
我整天都在解决此错误,但我无能为力。我已经在students_controller控制器中实现了before_action:
class StudentsController < ApplicationController
before_action :configure_devise_params, if: :devise_controller?
def configure_devise_params
devise_parameter_sanitizer.permit(:sign_up) do |user|
user.permit(:codigo, :documento, :nombres, :apellidos, :es_egresado, :email, :password, :password_confirmation)
end
end
...
end
但是问题仍然没有解决。 当我卸载devise,从中删除所有引用,并在控制器中实现强大的参数时,也会发生相同的错误,如果没有此注册表,则可以令人满意地工作。但是,由于具有强大的参数,而devise无效,因此它会在SQL命令中将数据传递给null。
学生数据库如下:
create_table "students", id: false, force: :cascade do |t|
t.integer "codigo", null: false
t.integer "documento", null: false
t.string "nombres", null: false
t.string "apellidos", null: false
t.integer "es_egresado", null: false
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.decimal "promedio_carrera"
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.index ["documento"], name: "index_students_on_documento", unique: true
t.index ["email"], name: "index_students_on_email", unique: true
t.index ["reset_password_token"], name: "index_students_on_reset_password_token", unique: true
end
其实现迁移如下:
class DeviseCreateStudents < ActiveRecord::Migration[5.1]
def change
create_table :students, {
:id => false,
:primary_key => :codigo
} do |t|
## Database authenticatable
t.integer :codigo, null: false
t.integer :documento, null: false
t.string :nombres, null: false
t.string :apellidos, null: false
t.integer :es_egresado, null: false
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
t.decimal :promedio_carrera, null: true
## 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 :students, :email, unique: true
add_index :students, :reset_password_token, unique: true
add_index :students, :documento, unique: true
# add_index :students, :confirmation_token, unique: true
# add_index :students, :unlock_token, unique: true
end
end
参数:
{"utf8"=>"✓",
"authenticity_token"=>"6zdENP1iREYYM+qpqtskqRJ+aB38NIX/nG9jFsoGlImqUVyS9bsmBF6Uc7xvDD/J50/zamlZbbm2rwAaCgOmuw==",
"student"=>
{"codigo"=>"625762",
"documento"=>"107526792",
"nombres"=>"Carlos",
"apellidos"=>"Garnica",
"es_egresado"=>"0",
"email"=>"wcarlosfg.1234567890@hotmail.com",
"password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]"},
"commit"=>"Registrar"}
我还澄清了,当我创建另一个Student表时,删除了前一个表,并且删除了字段的null选项,该错误不会出现,但是应该保存的字段在数据库中仍为NULL < / p>
更新:修改数据库,使所有字段都为空,无论表单中是否包含数据,表单都会发送空字段,这种情况非常少见。对对象进行检查时,它显示以下内容:
irb(main):002:0> Student.last
Student Load (0.0ms) SELECT "students".* FROM "students" ORDER BY "students"."id" DESC LIMIT ? [["LIMIT", 1]]
=> #<Student id: 2, codigo: nil, documento: nil, nombres: nil, apellidos: nil, es_egresado: nil, promedio_carrera: nil, email: "wcarlosfg.1234567890@hotmail.com", created_at: "2018-09-30 07:46:39", updated_at: "2018-09-30 07:46:39">
解决方案::看了一天的错误之后,唯一的解决方案是覆盖记录的devise驱动程序,以此,我能够添加逻辑并实现强大的参数来制作注册表正常工作。