ฉันscript/generate migration
จะสร้างตารางการเข้าร่วมสำหรับhas_and_belongs_to_many
ความสัมพันธ์ได้อย่างไร
แอปพลิเคชันทำงานบน Rails 2.3.2 แต่ฉันติดตั้ง Rails 3.0.3 ไว้ด้วย
ฉันscript/generate migration
จะสร้างตารางการเข้าร่วมสำหรับhas_and_belongs_to_many
ความสัมพันธ์ได้อย่างไร
แอปพลิเคชันทำงานบน Rails 2.3.2 แต่ฉันติดตั้ง Rails 3.0.3 ไว้ด้วย
คำตอบ:
ที่ไหน:
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
(สังเกตชื่อตารางจะแสดงทั้งตารางรวมตามลำดับตัวอักษร)
จากนั้นสำหรับราง 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) หรือไม่?
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ฉันได้อัปเดตเพื่อลบรหัสและการประทับเวลา ... โดยทั่วไปMattDiPasquale
และnunopolonia
ถูกต้อง: ต้องไม่มีรหัสและต้องไม่มีการประทับเวลามิฉะนั้นรางจะไม่อนุญาตให้has_and_belongs_to_many
ทำงาน
script/generate migration
...
คุณควรตั้งชื่อตารางเป็นชื่อของ 2 รุ่นที่คุณต้องการเชื่อมต่อตามลำดับตัวอักษรและใส่รหัสรุ่นทั้งสองในตาราง จากนั้นเชื่อมต่อแต่ละรุ่นเข้าด้วยกันเพื่อสร้างการเชื่อมโยงในแบบจำลอง
นี่คือตัวอย่าง:
# 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
คำตอบด้านบนแสดงดัชนีผสมที่ฉันไม่เชื่อว่าจะใช้ในการค้นหาแอปเปิ้ลจากส้ม
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' มีประโยชน์และการสนทนาก็เช่นกัน
ในราง 4 คุณสามารถใช้งานได้ง่าย
create_join_table: table1s,: table2s
มันคือทั้งหมด.
ข้อควรระวัง: คุณต้อง offord table1, table2 ด้วยตัวอักษรและตัวเลข
ฉันชอบทำ:
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
จะล้มเหลวหากอยู่ในการโยกย้ายเดียวกันกับที่สร้างตาราง