has_and_belongs_to_many 连接表的 Rails 迁移

发布于 2024-10-06 11:44:02 字数 128 浏览 6 评论 0原文

如何执行脚本/生成迁移来为has_and_belongs_to_many关系创建联接表?

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

How do I do a script/generate migration to create a join table for a has_and_belongs_to_many relationship?

The application runs on Rails 2.3.2, but I also have Rails 3.0.3 installed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

活雷疯 2024-10-13 11:44:02

其中:

class Teacher < ActiveRecord::Base
  has_and_belongs_to_many :students
end

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

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

,然后仅对于 Rails 3 及更低版本,您需要编辑生成的迁移,以便不会创建 id 字段:

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

Where:

class Teacher < ActiveRecord::Base
  has_and_belongs_to_many :students
end

and

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 < 3

script/generate migration students_teachers student_id:integer teacher_id:integer

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

and then for rails 3 and below only, you need to edit your generated migration so an id field is not created:

create_table :students_teachers, :id => false do |t|
屋顶上的小猫咪 2024-10-13 11:44:02

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)

如果您使用 :独特=> true 在索引上,那么你应该(在rails3中)传递 :uniq =>; truehas_and_belongs_to_many

更多信息:Rails 文档

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

A has_and_belongs_to_many table must match this format. I'm assuming the two models to be joined by has_and_belongs_to_many are already in the DB : apples and oranges:

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)

If you use the :unique => true on the index, then you should (in rails3) pass :uniq => true to has_and_belongs_to_many.

More information: Rails Docs

UPDATED 2010-12-13 I've updated it to remove the id and timestamps... Basically ma11hew28 and nunopolonia are correct: There must not be an id and there must not be timestamps or rails won't allow has_and_belongs_to_many to work.

自由如风 2024-10-13 11:44:02

您应该按字母顺序将要连接的 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

You should name the table the names of 2 models you want to connect by alphabetical order
and put the two model id's in the table.
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

But this is not very flexible and you should think about using has_many :through

拥抱影子 2024-10-13 11:44:02

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

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)

我确实发现基于“The Doctor What”的答案很有用,而且讨论当然也是如此。

The top answer shows a composite index that I don't believe will be used to lookup apples from oranges.

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.

如歌彻婉言 2024-10-13 11:44:02

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

create_join_table :table1s, :table2s

就可以了。

注意:您必须提供包含字母数字的 table1、table2。

In rails 4, you can simple use

create_join_table :table1s, :table2s

it is all.

Caution: you must offord table1, table2 with alphanumeric.

潦草背影 2024-10-13 11:44:02

Associations Rails 指南 很棒,但没有准确解释如何创建连接表。

不过,Migrations Rails 指南解释了如何进行联接桌子:

迁移方法 create_join_table 创建一个 HABTM(具有并属于多个)连接表。典型用途是:

create_join_table:产品、:类别

默认情况下,连接表的名称来自提供给 create_join_table 的前两个参数的并集,按字母顺序排列。

This HABTM section of the Associations Rails Guide is great, but doesn't explain exactly how to create a join table.

However, the Migrations Rails Guide explains how to make a join table:

The migration method create_join_table creates an HABTM (has and belongs to many) join table. A typical use would be:

create_join_table :products, :categories

By default, the name of the join table comes from the union of the first two arguments provided to create_join_table, in alphabetical order.

所谓喜欢 2024-10-13 11:44:02

我喜欢这样做:

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

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

I like doing:

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

I like having index on these columns because I'll often be doing lookups using these columns.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文