我们使用CanCan并管理数据库中的角色,使用https://github.com/ryanb/cancan/wiki/Separate-Role-Model除此之外,我们使用的是hasandbelongs_to_many,而不是"has_many:through"
我们的模式中有以下内容:
create_table "roles", :force => true do |t|
t.string "name", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "members_roles", :force => true do |t|
t.integer "member_id"
t.integer "role_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
在我们的模型中,我们有:
class Member < ActiveRecord::Base
has_and_belongs_to_many :roles
end
class Role < ActiveRecord::Base
has_and_belongs_to_many :members
end
现在,当我试图给一个成员一个新的角色时,它就死了。例如,在控制台中:
1.9.3p194 :001 > m = Member.find('test1')
Member Load (0.3ms) SELECT "members".* FROM "members" WHERE "members"."slug" = 'test1' LIMIT 1
=> #<Member id: 1, email: "test1@example.com", encrypted_password: "$2a$10$4VWJX07qwB9Lu5vtGAoQgOcCCRD9i8cgcxN8KGHBMaNL...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, confirmation_token: nil, confirmed_at: "2013-02-14 03:58:24", confirmation_sent_at: "2013-02-14 03:58:23", unconfirmed_email: nil, failed_attempts: 0, unlock_token: nil, locked_at: nil, created_at: "2013-02-14 03:58:23", updated_at: "2013-02-14 03:58:24", login_name: "test1", slug: "test1", tos_agreement: nil, show_email: nil, location: nil, latitude: nil, longitude: nil>
1.9.3p194 :002 > Role.all
Role Load (0.1ms) SELECT "roles".* FROM "roles"
=> []
1.9.3p194 :003 > r = Role.create(:name => 'foo')
(0.1ms) begin transaction
SQL (6.5ms) INSERT INTO "roles" ("created_at", "name", "updated_at") VALUES (?, ?, ?) [["created_at", Thu, 14 Feb 2013 04:01:29 UTC +00:00], ["description", nil], ["name", "foo"], ["updated_at", Thu, 14 Feb 2013 04:01:29 UTC +00:00]]
(746.2ms) commit transaction
=> #<Role id: 1, name: "foo", description: nil, created_at: "2013-02-14 04:01:29", updated_at: "2013-02-14 04:01:29">
1.9.3p194 :004 > m.roles << r
(0.1ms) begin transaction
(0.3ms) INSERT INTO "members_roles" ("member_id", "role_id") VALUES (1, 1)
(0.1ms) rollback transaction
ActiveRecord::StatementInvalid: SQLite3::ConstraintException: constraint failed: INSERT INTO "members_roles" ("member_id", "role_id") VALUES (1, 1)
(然后是大量的回溯,除非有人要求,否则我不会费心复制。)
我们究竟为什么会得到这个ConstraintException?
我认为您需要创建没有主键的members_roles
表,以便通过在迁移中的create_table
方法中指定:id => false
来使用has_and_belongs_to_many
关联。
rails文档中有一个如何做到这一点的示例:http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_and_belongs_to_many