has_and_belongs_to_many连接表的Rails迁移

时间:2010-12-07 20:18:15

标签: ruby-on-rails migration code-generation has-and-belongs-to-many

如何script/generate migrationhas_and_belongs_to_many关系创建联接表?

应用程序在Rails 2.3.2上运行,但我也安装了Rails 3.0.3。

6 个答案:

答案 0 :(得分:225)

其中:

class Teacher < ActiveRecord::Base
  has_and_belongs_to_many :students
end

class Student < ActiveRecord::Base
  has_and_belongs_to_many :teachers
end

for rails 4:

rails generate migration CreateJoinTableStudentTeacher student teacher

for rails 3:

rails generate migration students_teachers student_id:integer teacher_id:integer

for rails&lt; 3

script/generate migration students_teachers student_id:integer teacher_id:integer

(注意表名按字母顺序列出两个连接表)

然后仅针对rails 3及以下版本,您需要编辑生成的迁移,以便不创建id字段:

create_table :students_teachers, :id => false do |t|

答案 1 :(得分:138)

has_and_belongs_to_many表必须与此格式匹配。我假设has_and_belongs_to_many加入的两个模型已经在数据库中:applesoranges

create_table :apples_oranges, :id => false do |t|
  t.references :apple, :null => false
  t.references :orange, :null => false
end

# Adding the index can massively speed up join tables. Don't use the
# unique if you allow duplicates.
add_index(:apples_oranges, [:apple_id, :orange_id], :unique => true)

如果您在索引上使用:unique => true,那么您应该(在rails3中)将:uniq => true传递给has_and_belongs_to_many

更多信息:Rails Docs

更新2010-12-13 我已更新它以删除ID和时间戳...基本上MattDiPasqualenunopolonia是正确的:一定不能有id并且不得有时间戳或rails不允许has_and_belongs_to_many工作。

答案 2 :(得分:14)

您应该按字母顺序将表格命名为2个模型的名称 并将两个模型ID放在表中。 然后将每个模型相互连接,在模型中创建关联。

以下是一个例子:

# in migration
def self.up
  create_table 'categories_products', :id => false do |t|
    t.column :category_id, :integer
    t.column :product_id, :integer
  end
end

# models/product.rb
has_and_belongs_to_many :categories

# models/category.rb
has_and_belongs_to_many :products

但这不是很灵活,你应该考虑使用has_many:through

答案 3 :(得分:6)

最佳答案显示了一个综合索引,我不相信它将用于从橙子中查找苹果。

create_table :apples_oranges, :id => false do |t|
  t.references :apple, :null => false
  t.references :orange, :null => false
end

# Adding the index can massively speed up join tables.
# This enforces uniqueness and speeds up apple->oranges lookups.
add_index(:apples_oranges, [:apple_id, :orange_id], :unique => true)
# This speeds up orange->apple lookups
add_index(:apples_oranges, :orange_id)

我确实找到了答案,这是基于'医生什么'有用,讨论当然也是如此。

答案 4 :(得分:4)

在rails 4中,您可以简单地使用

create_join_table:table1s,:table2s

总而言之。

警告:你必须使用字母数字来表示table1,table2。

答案 5 :(得分:1)

我喜欢这样做:

rails g migration CreateJoinedTable model1:references model2:references。这样我就得到了这样的迁移:

class CreateJoinedTable < ActiveRecord::Migration
  def change
    create_table :joined_tables do |t|
      t.references :trip, index: true
      t.references :category, index: true
    end
    add_foreign_key :joined_tables, :trips
    add_foreign_key :joined_tables, :categories
  end
end

我喜欢在这些列上使用索引,因为我经常使用这些列进行查找。