2011-06-12 55 views
1

当你有多对多的关系时,你必须显式创建中间连接表吗?如何将外键添加到迁移?我有一个用户模型和一个书籍模型。我已安装foreigner。这是我的代码到目前为止。有人可以告诉我如何从这里出发吗?如何在多对多关系中添加外键?

用户

class User < ActiveRecord::Base 
    has_and_belongs_to_many :books 
    # Include default devise modules. Others available are: 
    # :token_authenticatable, :lockable, :timeoutable and :activatable 
    devise :database_authenticatable, :registerable, 
     :recoverable, :rememberable, :trackable, :validatable 

    # Setup accessible (or protected) attributes for your model 
    attr_accessible :email, :password, :password_confirmation 
end 

Book模型

class Book < ActiveRecord::Base 
    has_and_belongs_to_many :users 
end 

迁移书籍

class CreateBooks < ActiveRecord::Migration 

    def self.up 
    create_table :books do |t| 
     t.string :title 
     t.string :author 
     t.timestamps 
    end 
    end 

    def self.down 
    drop_table :books 
    end 
end 

迁移用户

class DeviseCreateUsers < ActiveRecord::Migration 
    def self.up 
    create_table(:users) do |t| 
     t.database_authenticatable :null => false 
     t.recoverable 
     t.rememberable 
     t.trackable 
     # t.lockable :lock_strategy => :failed_attempts, :unlock_strategy => :both 
     t.timestamps 
    end 
    add_index :users, :email, :unique => true 
    add_index :users, :reset_password_token, :unique => true 
    # add_index :users, :unlock_token, :unique => true 
    end 

    def self.down 
    drop_table :users 
    end 
end 

回答

2

是的,你需要一个连接表。使用has_and_belongs_to_many时的惯例是命名连接表,如model1_model2。因此,在这种情况下,你的迁移需要看起来像这样:

create_table :books_users, :id => false do |t| 
    t.integer :user_id, :null => false 
    t.integer :book_id, :null => false 
end 

注意的:ID =>虚假的一部分,这是确保连接表不会自动获得自己的ID。

+1

您可能还想查看has_many:通过has_and_belongs_to_many。用has_many:通过你将为连接表创建一个有意义的模型。在这种情况下,它可能像所有权一样。看看这个Railscasts插曲,了解更多有关这两种方法的信息:http://railscasts.com/episodes/47-two-many-to-many – dpb 2011-06-12 23:52:34

+0

表应该是books_users,因为书籍在用户之前按字母顺序排列 – bruno077 2011-06-12 23:58:06

+0

谢谢!我已经更新了答案。 – dpb 2011-06-13 00:05:23