关联中的Devise和Simple_form错误

时间:2018-05-02 10:04:28

标签: ruby-on-rails ruby devise simple-form

我在创建注册到我的rails应用程序时遇到问题,我正在使用Devise和Simple_form,我有2个模型(用户和部门),用户belongs_to:部门和部门has_many:用户,我得到一个错误,当我尝试注册说部门必须退出。

设计/注册/ new.html.erb

    <h2>Sign up</h2>

<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.input :username, required: true, autofocus: true %>
    <%= f.input :email, required: true %>
    <%= f.input :password, required: true, hint: ("#{@minimum_password_length} characters minimum" if @minimum_password_length) %>
    <%= f.input :password_confirmation, required: true %><br>
    <%= f.association :department %>
  </div>

  <div class="form-actions">
    <%= f.button :submit, "Sign up" %>
  </div>
<% end %>

<%= render "devise/shared/links" %>

user.rb

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  validates_uniqueness_of :email, :username
  belongs_to :department
  has_and_belongs_to_many :courses
end

department.rb

class Department < ApplicationRecord
  has_many :users
  has_many :courses
end

我使用seeds.rb填充departments表并通过mysql控制台检查。

schema.rb

ActiveRecord::Schema.define(version: 20180502071349) do

  create_table "courses", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1" do |t|
    t.string "name"
    t.text "description"
    t.bigint "department_id"
    t.string "instructor_name"
    t.integer "credit_hours"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["department_id"], name: "index_courses_on_department_id"
  end

  create_table "departments", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1" do |t|
    t.string "name"
    t.text "description"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "enrollments", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1" do |t|
    t.bigint "user_id"
    t.bigint "courses_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["courses_id"], name: "index_enrollments_on_courses_id"
    t.index ["user_id"], name: "index_enrollments_on_user_id"
  end

  create_table "users", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1" do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "username", default: "", null: false
    t.bigint "department_id"
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    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"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["department_id"], name: "index_users_on_department_id"
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
    t.index ["username"], name: "index_users_on_username", unique: true
  end

  add_foreign_key "courses", "departments"
  add_foreign_key "enrollments", "courses", column: "courses_id"
  add_foreign_key "enrollments", "users"
  add_foreign_key "users", "departments"
end

迁移文件

class CreateDepartments < ActiveRecord::Migration[5.1]
  def change
    create_table :departments do |t|
      t.string :name
      t.text :description

      t.timestamps
    end
  end
end
# frozen_string_literal: true

class DeviseCreateUsers < ActiveRecord::Migration[5.1]
  def change
    create_table :users do |t|
      ## Database authenticatable
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""
      t.string :username,           null: false, default: ""
      t.references :department, foreign_key: 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 :users, :email,                unique: true
    add_index :users, :reset_password_token, unique: true
    add_index :users, :username,             unique: true
    # add_index :users, :confirmation_token,   unique: true
    # add_index :users, :unlock_token,         unique: true
  end
end
class CreateCourses < ActiveRecord::Migration[5.1]
  def change
    create_table :courses do |t|
      t.string :name
      t.text :description
      t.references :department, foreign_key: true
      t.string :instructor_name
      t.integer :credit_hours

      t.timestamps
    end
    create_table :enrollments do |t|
      t.references :user, foreign_key: true
      t.references :courses, foreign_key: true

      t.timestamps
    end
  end
end

P.S。,我刚刚开始使用rails并感谢您的帮助。

Error screenshot:

2 个答案:

答案 0 :(得分:3)

Devise对您的无标准JSONObject字段一无所知,并将其过滤为未经许可的参数。

创建自己的注册控制器(扩展Devise),然后自定义这些方法:

department_id

这只是一个样本。感受真实的字段名称

答案 1 :(得分:1)

自5.1以后的Rails对新生成的应用程序进行了必需的belongs_to验证。

您可以通过以下方式禁用它:

class User < ApplicationRecord
  belongs_to :department, optional: true
end

通过这种方式,您可以先创建一个空部门的用户。