0

我们使用 CanCan 并管理数据库中的角色,使用https://github.com/ryanb/cancan/wiki/Separate-Role-Model上的说明,除了我们使用 has_and_belongs_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?

4

1 回答 1

2

我相信您需要通过在迁移中的方法中指定来创建members_roles没有主键的表才能使用关联。has_and_belongs_to_many:id => falsecreate_table

在 Rails 文档中有一个如何执行此操作的示例:http: //api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_and_belongs_to_many

于 2013-02-14T04:55:21.823 回答