has_and_belongs_to_many 조인 테이블에 대한 Rails 마이그레이션


답변:


228

어디:

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|

16
이것은 실제로 질문에 답하는 유일한 답변입니다.
pingu

8
@pingu : 적어도 Rails 3.2에서는 작동하지 않는다는 점만 제외하면. 생성 된 마이그레이션 파일이 비어 있습니다.
hoffmanc jul.

7
Rails 4에서 작동합니다.
Felipe Zavan 2014

2
@hoffmanc 필드를 지정하지 않으면 빈 마이그레이션 파일이 생성됩니다. Rails가 마이그레이션 파일에 자동으로 추가하도록하려면 필드를 지정해야합니다.
Andrew

1
안녕하세요, rails generate migration CreateJoinTableTeacherStudent teacher student대신 시도 rails generate migration CreateJoinTableStudentTeacher student teacher하고 있습니다. 동일합니까? S (학생)는 T (교사) 전에해야합니까?
zx1986 2015

138

has_and_belongs_to_many표에서는이 형식과 일치해야합니다. 나는 두 가지 모델이 합류 할 수 있으리라 믿고있어 has_and_belongs_to_manyDB에 이미 : 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)

:unique => true색인에서를 사용하는 경우 (rails3에서)으로 전달해야 :uniq => true합니다 has_and_belongs_to_many.

추가 정보 : Rails Docs

2010-12-13 업데이트] 나는 기본적으로 ... ID와 타임 스탬프를 제거하도록 업데이트되었습니다 MattDiPasqualenunopolonia올바른 :의 ID가 없어야합니다 거기에 타임 스탬프해서는 안이나 레일이 허용하지 않는 has_and_belongs_to_many일에.


6
실제로 조인 테이블에는 두 개의 참조 열만 있어야하며 ID 또는 타임 스탬프 열이 없어야합니다. 다음은 귀하가 제공 한 링크에서 has_and_belongs_to_many 마이그레이션 의 더 나은 예입니다 . 명령 줄에서 할 방법을 찾고 있어요 script/generate migration...
ma11hew28 dec.

음, 타임 스탬프가 필요하지 않습니다. 내 예에서는 선택 사항으로 표시했습니다. 그래도 ID를 추가하는 것이 좋습니다. ID 또는 타임 스탬프가 유용 할 수있는 경우가 있습니다. 하지만 신분증을 강력히 추천합니다.
docwhat

확인. ID가 유용한 경우는 무엇입니까?
ma11hew28 2010

한 가지 예는 관계가 견해를 가질만큼 중요한 경우입니다. 또한 반복적으로 조회하는 대신 relationship.id를 전달하여 데이터베이스 액세스 속도를 높일 수 있습니다. 또한 데이터베이스 문제를보다 쉽게 ​​해결할 수 있습니다. 특히 다른 열의 ID가 정말 높은 경우. id : 54321-id : 67890 대신 id : 12345를 기억하는 것이 더 쉽습니다.하지만 테이블이 정말 커지면 각 관계에 대해 다른 ID를 할당하지 않음으로써 공간을 절약 할 수 있습니다.
docwhat

2
다중 열 인덱스가 이에 대한 올바른 해결책이라고 생각하지 않습니다. 특정 사과에 대한 쿼리에서 관련 오렌지를 찾는 데는 작동하지만 그 반대는 아닙니다. 두 개의 단일 열 인덱스를 사용하면 특정 사과, 주황색 조합의 존재 확인에 약간의 손실을 입히면 서 양방향을 효율적으로 쿼리 할 수 ​​있습니다.
Joseph Lord

14

연결하고자하는 두 모델의 이름을 알파벳 순서로 테이블에 지정하고 두 모델 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 사용에 대해 생각해야합니다.


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)

나는 이것이 'The Doctor What'이 유용하고 토론에 근거한 대답을 찾았습니다.


4

Rails 4에서는 간단하게 사용할 수 있습니다.

create_join_table : table1s, : table2s

그게 다입니다.

주의 : 영숫자로 table1, table2를 입력해야합니다.


이것은 좋은 최신 솔루션입니다. 조인 테이블은 모델로 액세스 할 수 없지만 조인 된 두 테이블 모두에 설정된 has_and_belongs_to_many 관계를 통해 액세스 할 수 있습니다.
Taylored 웹 사이트

1

나는하는 것을 좋아한다 :

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테이블을 생성 한 마이그레이션과 동일한 마이그레이션에 배치하면 실패합니다.
Adib Saad 2015
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.