播种数据库时类型不匹配
Type mismatch when seeding database
我正在尝试为应用程序数据库播种,但出现以下错误:
ActiveRecord::AssociationTypeMismatch: Role(#97332160) expected,
got Fixnum(#76482890)
这里是我的schema.rb
关于两个table问题的部分:
create_table "roles", force: :cascade do |t|
t.string "role", limit: 50, null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "first_name", limit: 100, null: false
t.string "surname", limit: 100, null: false
t.string "email", limit: 255
t.integer "role_id", limit: 11
t.string "password", limit: 150
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "users", ["first_name"], name: "index_users_on_first_name", using: :btree
add_index "users", ["role_id"], name: "index_users_on_role_id", using: :btree
add_index "users", ["surname"], name: "index_users_on_surname", using: :btree
add_foreign_key "users", "roles"
这是我的 seeds.rb
命令:
rl = Role.create(role: "root")
User.create(first_name: "Edvaldo", surname: "Silva de Almeida Júnior", email: "edvaldo@my.domain.com", role_id: rl.id, password: "my_password")
rl = Role.create(role: "admin")
User.create(first_name: "Daiely", surname: "Fanchin", email: "daiely@my.domain.com", role_id: rl.id, password: "other_password")
rl = Role.create(role: "user")
User.create(first_name: "César", surname: "Silva", email: "cesar@my.domain.com", role_id: rl.id, password: "yet_other_password")
我发现 a question 接受的答案建议我应该这样做:
rl = Role.create(role: "root")
User.create(first_name: "Edvaldo", surname: "Silva de Almeida Júnior", email: "edvaldo@my.domain.com", role_id: Role.find(rl.id), password: "my_password")
我试过了,但得到了同样的错误!此外,我使用 role_id
作为关联,而不是角色本身。因此,就我而言,它应该收到 Fixnum
,而不是 Role
。
add_foreign_key "users", "roles"
这将为用户添加 role_id
列,无需单独编写 t.integer "role_id", limit: 11
应该有一些联想
class User < ActiveRecord::Base
belongs_to :role
end
和
create_table "users", force: :cascade do |t|
t.string "first_name", limit: 100, null: false
t.string "surname", limit: 100, null: false
t.string "email", limit: 255
t.reference "role", index: true
t.string "password", limit: 150
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_foreign_key "users", "roles", column: :role_id
希望它能解决它。
我在我的用户模型中添加了一个方法 set_default_role。
class User < ActiveRecord::Base
has_one :role
after_initialize :set_default_role, :if => :new_record?
def set_default_role
if User.count == 0
self.role ||= 1
else
self.role ||= 2
end
end
end
但是这个方法是错误的,我一改写就
def set_default_role
if User.count == 0
self.role_id ||= 1
else
self.role_id ||= 2
end
end
我的播种效果很好。
所以,问题是我尝试(在此方法内)将 Role 设置为 Fixnum。
这是对 Rails 新手的 建议 :播种不仅仅是将某些内容强加到您的数据库中。这是对您的模型的全面评估,有时错误可能是由某些方法的执行引起的,而不仅仅是您尝试加载的值。
你的问题很简单:
role_id: Role.find(rl.id)
.find()
returns 一个 Role
对象。
您的 create
方法需要 foreign_key
(整数)(role_id: [int]
)。
简单的修复方法是:
User.create(... role_id: Role.find(rl.id).id ...)
.. 或 ...
User.create(... role_id: rl.id ...)
...甚至更好...
User.create(... role: rl ...)
--
修复
真正的解决方法是 在您的数据库中设置 default
,或者像您在提交的答案中那样手动设置 role_id
。
我强烈建议使用数据库 default
,因为那样的话,您的应用程序中发生的事情并不重要 - 您的数据库将始终 "default" 到您设置的角色:
$ rails g migration SetDefaultForRole
$ db/migrate/set_default_for_role_____.rb
class SetDefaultForRole < ActiveRecord::Migration
def change
change_column :users, :role_id, :integer, default: 0
end
end
$ rake db:migrate
这样做的缺点是将设置此整数默认值(除非您再次更改数据库)。虽然这本身不是问题,但它会为您的 Role
模型创建一个 antipattern(IE,您可以创建任何角色,只要它是 在 初始角色之后你做了)。
--
另一种方法是为用户设置 Role
。
你已经有了这个;你可以清理它:
#app/models/user.rb
class User < ActiveRecord::Base
before_create :set_role, if: Proc.new { |m| m.role_id.blank? }
private
def set_role
self.role_id = "1" if User.count == 0
end
end
我正在尝试为应用程序数据库播种,但出现以下错误:
ActiveRecord::AssociationTypeMismatch: Role(#97332160) expected,
got Fixnum(#76482890)
这里是我的schema.rb
关于两个table问题的部分:
create_table "roles", force: :cascade do |t|
t.string "role", limit: 50, null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "first_name", limit: 100, null: false
t.string "surname", limit: 100, null: false
t.string "email", limit: 255
t.integer "role_id", limit: 11
t.string "password", limit: 150
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "users", ["first_name"], name: "index_users_on_first_name", using: :btree
add_index "users", ["role_id"], name: "index_users_on_role_id", using: :btree
add_index "users", ["surname"], name: "index_users_on_surname", using: :btree
add_foreign_key "users", "roles"
这是我的 seeds.rb
命令:
rl = Role.create(role: "root")
User.create(first_name: "Edvaldo", surname: "Silva de Almeida Júnior", email: "edvaldo@my.domain.com", role_id: rl.id, password: "my_password")
rl = Role.create(role: "admin")
User.create(first_name: "Daiely", surname: "Fanchin", email: "daiely@my.domain.com", role_id: rl.id, password: "other_password")
rl = Role.create(role: "user")
User.create(first_name: "César", surname: "Silva", email: "cesar@my.domain.com", role_id: rl.id, password: "yet_other_password")
我发现 a question 接受的答案建议我应该这样做:
rl = Role.create(role: "root")
User.create(first_name: "Edvaldo", surname: "Silva de Almeida Júnior", email: "edvaldo@my.domain.com", role_id: Role.find(rl.id), password: "my_password")
我试过了,但得到了同样的错误!此外,我使用 role_id
作为关联,而不是角色本身。因此,就我而言,它应该收到 Fixnum
,而不是 Role
。
add_foreign_key "users", "roles"
这将为用户添加 role_id
列,无需单独编写 t.integer "role_id", limit: 11
应该有一些联想
class User < ActiveRecord::Base
belongs_to :role
end
和
create_table "users", force: :cascade do |t|
t.string "first_name", limit: 100, null: false
t.string "surname", limit: 100, null: false
t.string "email", limit: 255
t.reference "role", index: true
t.string "password", limit: 150
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_foreign_key "users", "roles", column: :role_id
希望它能解决它。
我在我的用户模型中添加了一个方法 set_default_role。
class User < ActiveRecord::Base
has_one :role
after_initialize :set_default_role, :if => :new_record?
def set_default_role
if User.count == 0
self.role ||= 1
else
self.role ||= 2
end
end
end
但是这个方法是错误的,我一改写就
def set_default_role
if User.count == 0
self.role_id ||= 1
else
self.role_id ||= 2
end
end
我的播种效果很好。
所以,问题是我尝试(在此方法内)将 Role 设置为 Fixnum。
这是对 Rails 新手的 建议 :播种不仅仅是将某些内容强加到您的数据库中。这是对您的模型的全面评估,有时错误可能是由某些方法的执行引起的,而不仅仅是您尝试加载的值。
你的问题很简单:
role_id: Role.find(rl.id)
.find()
returns 一个 Role
对象。
您的 create
方法需要 foreign_key
(整数)(role_id: [int]
)。
简单的修复方法是:
User.create(... role_id: Role.find(rl.id).id ...)
.. 或 ...
User.create(... role_id: rl.id ...)
...甚至更好...
User.create(... role: rl ...)
--
修复
真正的解决方法是 在您的数据库中设置 default
,或者像您在提交的答案中那样手动设置 role_id
。
我强烈建议使用数据库 default
,因为那样的话,您的应用程序中发生的事情并不重要 - 您的数据库将始终 "default" 到您设置的角色:
$ rails g migration SetDefaultForRole
$ db/migrate/set_default_for_role_____.rb
class SetDefaultForRole < ActiveRecord::Migration
def change
change_column :users, :role_id, :integer, default: 0
end
end
$ rake db:migrate
这样做的缺点是将设置此整数默认值(除非您再次更改数据库)。虽然这本身不是问题,但它会为您的 Role
模型创建一个 antipattern(IE,您可以创建任何角色,只要它是 在 初始角色之后你做了)。
--
另一种方法是为用户设置 Role
。
你已经有了这个;你可以清理它:
#app/models/user.rb
class User < ActiveRecord::Base
before_create :set_role, if: Proc.new { |m| m.role_id.blank? }
private
def set_role
self.role_id = "1" if User.count == 0
end
end