Has_and_properties_to_many 联接表的 Rails 迁移

如何执行 script/generate migration以创建 has_and_belongs_to_many关系的连接表?

这个应用程序运行在 Rails2.3.2上,但是我也安装了 Rails3.0.3。

68189 次浏览

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

More information: Rails Docs

更新2010-12-13 我更新了它,删除了 id 和时间戳... ... 基本上 ma11hew28nunopolonia是正确的: 不能有 id 和时间戳,或者 Rails 不允许 has_and_belongs_to_many工作。

你应该给这个表命名为你想要通过字母顺序连接的两个模型的名字 把两个模型 ID 放在桌子上。 Then connect each model to each other creating the associations in the model.

Here's an example:

# 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

地点:

class Teacher < ActiveRecord::Base
has_and_belongs_to_many :students
end

and

class Student < ActiveRecord::Base
has_and_belongs_to_many :teachers
end

铁轨4:

rails generate migration CreateJoinTableStudentTeacher student teacher

铁轨3:

rails generate migration students_teachers student_id:integer teacher_id:integer

铁轨 < 3

script/generate migration students_teachers student_id:integer teacher_id:integer

(note the table name lists both join tables in alphabetical order)

然后,对于 Rails 3及以下版本,您需要编辑生成的迁移,这样就不会创建 id 字段:

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

最上面的答案显示了一个综合索引,我认为这个索引不会被用来从橘子中查找苹果。

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)

I did find the answer this is based on by 'The Doctor What' useful and the discussion certainly so too.

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

Create _ join _ table: table1s,: table2s

就是这样。

注意: 您必须提供带有字母数字的表1、表2。

我喜欢做:

rails g migration CreateJoinedTable model1:references model2:references. That way I get a migration that looks like this:

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

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

协会铁路指南的 HABTM 部分非常棒,但是没有准确地解释如何创建连接表。

然而,迁移指南解释了如何创建联接表:

迁移方法 create_join_table创建一个 HABTM (拥有和属于多个)联接表:

create_join_table :products, :categories

默认情况下,连接表的名称来自为 create _ join _ table 提供的前两个参数的联合字母顺序。