0

「has_many :through」ではなく has_and_belongs_to_many を使用していることとは別に、https://github.com/ryanb/cancan/wiki/Separate-Role-Modelの手順を使用して、CanCan を使用し、データベースでロールを管理しています。

スキーマには次のものがあります。

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 に答える