生成迁移-创建联接表


71

我经历了许多期待SOgoogle职位产生连接表的迁移has many and belongs to many协会并没有什么工作。

所有解决方案都生成一个空的迁移文件。

我正在使用rails 3.2.13,我有两个表:security_usersassignments。这些是我尝试过的一些事情:

rails generate migration assignments_security_users

rails generate migration create_assignments_security_users

rails generate migration create_assignments_security_users_join_table

rails g migration create_join_table :products, :categories (following the official documentation)

rails generate migration security_users_assignments security_user:belongs_to assignments:belongs_to 

谁能说出如何在两个表之间创建联接表迁移?

Answers:


44

运行以下命令以生成空的迁移文件(该文件不会自动填充,您需要自己填充):

rails generate migration assignments_security_users

打开生成的迁移文件并添加以下代码:

class AssignmentsSecurityUsers < ActiveRecord::Migration
  def change
    create_table :assignments_security_users, :id => false do |t|
      t.integer :assignment_id
      t.integer :security_user_id
    end
  end
end

然后rake db:migrate从您的终端运行。我用一个可能对您有所帮助的简单示例创建了一个关于many_to_many关系的测验


4
如果这样做,请确保添加null: false到字段定义中。例如:t.integer :assignment_id, null: false。这样可以防止出现可怕的情况,即最终导致连接表无处指向,数据丢失完整性并且代码崩溃。(或者最终到处都是丑陋且易错的防护代码)。
黑暗的推子

1
我同意@Powers,并补充一点,也许是向这些列添加索引的想法?
BKSpurgeon '16

180

要在命令行中自动填充create_join_table命令,它应如下所示:

rails g migration CreateJoinTableProductsSuppliers products suppliers

对于产品模型和供应商模型。Rails将创建一个名为“ products_suppliers”的表。注意多元化。

(请注意,generation命令可以缩短为g


10
使用CreateJoinTable时要小心,因为在处理带有my_products和my_suppliers之类的前缀的表时,它将生成一个像my_products_my_suppliers这样的联接表,而ActiveRecord希望它是my_products_suppliers。然后,像MyProduct.first.my_suppliers这样的关联将无法工作!检查github.com/rails/rails/issues/13683-我的解决方案是继续使用CreateJoinTable,但要添加table_name: :my_products_suppliers迁移guides.rubyonrails.org/migrations.html
jj_ 2014年

3
我喜欢这个解决方案胜过接受的答案
bradpotts


1

我相信这将是Rails 5的更新答案

create_table :join_table_name do |t|
  t.references :table_name, foreign_key: true
  t.references :other_table_name, foreign_key: true
end

您将如何为Rails 6做到这一点?rails g migration CreateJoinTableBookGenre book genre例如,运行,将创建2条注释掉的行:first t.index [:book_id, :genre_id],和2nd-相同,但带有:book_id和被:genre_id交换。我很困惑; 我应该选择一个还是取消注释?
verified_tinker

运行rails g migration AnyNameYouWantToUse这将生成一个迁移文件,在其中添加代码def change(应为空)。然后跑步rails db:migrate
Cody Elhard '20
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.