【发布时间】:2011-05-21 20:04:53
【问题描述】:
如何使用script/generate migration 为has_and_belongs_to_many 关系创建连接表?
应用程序在 Rails 2.3.2 上运行,但我也安装了 Rails 3.0.3。
【问题讨论】:
标签: ruby-on-rails migration code-generation has-and-belongs-to-many
如何使用script/generate migration 为has_and_belongs_to_many 关系创建连接表?
应用程序在 Rails 2.3.2 上运行,但我也安装了 Rails 3.0.3。
【问题讨论】:
标签: ruby-on-rails migration code-generation has-and-belongs-to-many
我喜欢做:
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
我喜欢在这些列上建立索引,因为我经常使用这些列进行查找。
【讨论】:
add_foreign_key 置于与创建表的迁移相同的迁移中,则将失败。
在rails 4中,你可以简单地使用
create_join_table :table1s, :table2s
就是这样。
注意:表 1、表 2 必须包含字母数字。
【讨论】:
地点:
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
用于导轨
script/generate migration students_teachers student_id:integer teacher_id:integer
(注意表名按字母顺序列出了两个连接表)
然后仅对于 rails 3 及以下版本,您需要编辑生成的迁移,以便不创建 id 字段:
create_table :students_teachers, :id => false do |t|
【讨论】:
rails generate migration CreateJoinTableTeacherStudent teacher student 而不是rails generate migration CreateJoinTableStudentTeacher student teacher,是一样的吗? S(tudent) 需要在 T(eacher) 之前吗?
最佳答案显示了一个复合索引,我认为它不会用于从橘子中查找苹果。
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)
我确实发现这个基于“什么医生”的答案很有用,而且讨论当然也很有用。
【讨论】:
has_and_belongs_to_many 表必须与此格式匹配。我假设has_and_belongs_to_many 加入的两个模型已经在数据库中:apples 和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)
如果您在索引上使用:unique => true,那么您应该(在rails3 中)将:uniq => true 传递给has_and_belongs_to_many。
更多信息:Rails Docs
2010-12-13 更新我已经更新它以删除 id 和时间戳...基本上MattDiPasquale 和 nunopolonia 是正确的:不能有 id,必须有不是时间戳,否则 Rails 将不允许 has_and_belongs_to_many 工作。
【讨论】:
script/generate migration ...
您应该按字母顺序将表命名为要连接的 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
【讨论】: