has_and_belongs_to_many连接表的Rails迁移

ma1*_*w28 122 migration code-generation ruby-on-rails has-and-belongs-to-many

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

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

dan*_*ave 227

哪里:

class Teacher < ActiveRecord::Base
  has_and_belongs_to_many :students
end
Run Code Online (Sandbox Code Playgroud)

class Student < ActiveRecord::Base
  has_and_belongs_to_many :teachers
end
Run Code Online (Sandbox Code Playgroud)

对于铁轨4:

rails generate migration CreateJoinTableStudentTeacher student teacher
Run Code Online (Sandbox Code Playgroud)

对于rails 3:

rails generate migration students_teachers student_id:integer teacher_id:integer
Run Code Online (Sandbox Code Playgroud)

for rails <3

script/generate migration students_teachers student_id:integer teacher_id:integer
Run Code Online (Sandbox Code Playgroud)

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

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

create_table :students_teachers, :id => false do |t|
Run Code Online (Sandbox Code Playgroud)

  • 这是实际回答问题的唯一回复. (16认同)
  • @pingu:除了它不起作用,至少在Rails 3.2中.生成的迁移文件为空. (8认同)
  • 适用于Rails 4. (7认同)
  • @hoffmanc如果您未指定任何字段,它将生成一个空的迁移文件.如果希望Rails自动将它们添加到迁移文件,则必须指定字段. (2认同)

doc*_*hat 138

一个has_and_belongs_to_many表必须格式相匹配.我假设要加入的两个模型has_and_belongs_to_many已经在DB中了: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)
Run Code Online (Sandbox Code Playgroud)

如果你使用:unique => true索引,那么你应该(在rails3中)传递:uniq => truehas_and_belongs_to_many.

更多信息:Rails Docs

已更新2010-12-13我已经更新了它删除ID和时间戳...基本上MattDiPasqualenunopolonia是正确的:不能有一个ID,并不能有时间戳或导轨不允许has_and_belongs_to_many工作.

  • 实际上,连接表应该只有两个引用列,并且没有id或timestamp列.以下是您提供的链接中[has_and_belongs_to_many migration](http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_and_belongs_to_many)的更好示例.我正在寻找一种方法,使用`script/generate migration`从命令行执行此操作... (6认同)
  • 我不认为多列索引是正确的解决方案.它适用于特定苹果的查询,以查找相关的橙子,但不是相反的方式.两个单列索引将允许有效地查询两个方向,可能在特定苹果,橙色组合的存在检查的小损失. (2认同)

nun*_*nia 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
Run Code Online (Sandbox Code Playgroud)

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


Jos*_*ord 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)
Run Code Online (Sandbox Code Playgroud)

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


zw9*_*963 5

在rails 4中,你可以简单的使用

create_join_table :table1s, :table2s

这就是全部。

注意:您必须不使用带有字母数字的表 1、表 2。


use*_*745 1

Associations Rails Guide的 HABTM 部分很棒,但没有准确解释如何创建连接表。

然而,Migrations Rails Guide解释了如何创建连接表:

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

create_join_table :products, :categories

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