生成迁移 - 创建连接表

Posted

技术标签:

【中文标题】生成迁移 - 创建连接表【英文标题】:Generate migration - create join table 【发布时间】:2013-07-19 20:52:58 【问题描述】:

我查看了许多 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 

谁能告诉如何在两个表之间创建连接表迁移?

【问题讨论】:

【参考方案1】:

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

rails g migration CreateJoinTableProductsSuppliers products suppliers

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

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

【讨论】:

使用 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 我比接受的答案更喜欢这个解决方案【参考方案2】:

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

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。我用一个简单的例子创建了a quiz on many_to_many relationships,可能会对你有所帮助。

【讨论】:

如果您这样做,请确保将null: false 添加到字段定义中。例如:t.integer :assignment_id, null: false。这将防止出现以下可怕情况:连接表无处指向、数据失去完整性并且代码崩溃。 (或者最终充斥着丑陋且容易出错的保护代码)。 我同意@Powers 并补充说,也许为这些列添加索引是一个想法? 需要注意的是,Rails 可以为您做的工作比这个答案建议的要多。请参阅下面的 ***.com/a/20672876/972128 以及该答案的 cmets。【参考方案3】:

我通常喜欢在创建连接表时也拥有“模型”文件。所以我愿意。

rails g model AssignmentSecurityUser assignments_security:references user:references

【讨论】:

【参考方案4】:

rails 中有用于连接表的嵌入式生成

rails g migration AddCityWorkerJoinTable cities:uniq workers

生成以下迁移

create_join_table :cities, :workers do |t|
  t.index [:city_id, :worker_id], unique: true
end

❗️注意:

型号名称应按字母顺序排列 仅将:uniq 放在第一个参数上

【讨论】:

【参考方案5】:

我相信这将是 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 个注释掉的行:第一行,t.index [:book_id, :genre_id] 和第二行——相同,但交换了 :book_id:genre_id。我糊涂了;我应该选择一个还是取消注释两者? run rails g migration AnyNameYouWantToUse 这将生成一个迁移文件,在def change 中添加代码(应该为空)。然后运行rails db:migrate

以上是关于生成迁移 - 创建连接表的主要内容,如果未能解决你的问题,请参考以下文章

如何指定Laravel用于迁移表的数据库连接?

has_and_belongs_to_many 连接表的 Rails 迁移

EF5生成的数据库在存在多个关系时不创建连接表

MySQL:创建具有自动增量的表并将生成的值与同一表的不同列的值连接起来

如何设置两个连接字符串 MySqlCommand 对象参数?

mysql数据库连接状态,不要做修改数据库表结构的操作;数据库迁移操作;