131 Stimmen

Rails hat_und_gehört_zu_vielen Migration

Ich habe zwei Modelle restaurant y user dass ich eine has_and_belongs_to_many Beziehung durchführen möchte.

Ich habe bereits die Modelldateien geöffnet und die has_and_belongs_to_many :restaurants y has_and_belongs_to_many :users

Ich nehme an, an dieser Stelle sollte ich in der Lage sein, etwas wie mit Rails 3 zu tun:

rails generate migration ....

aber alles, was ich versucht habe, scheint fehlzuschlagen. Ich bin sicher, dies ist etwas wirklich einfach ich bin neu zu Schienen, so dass ich noch lernen.

278voto

Dex Punkte 12167

Sie müssen eine separate Join-Tabelle hinzufügen, die nur eine restaurant_id y user_id (kein Primärschlüssel), in alphabetische Reihenfolge .

Führen Sie zunächst Ihre Migrationen durch und bearbeiten Sie dann die erzeugte Migrationsdatei.

Schiene 3

rails g migration create_restaurants_users_table

Schienen 4 :

rails g migration create_restaurants_users

Schiene 5

rails g migration CreateJoinTableRestaurantUser restaurants users

Von der docs :

Es gibt auch einen Generator, der Join-Tabellen erzeugt, wenn JoinTable Teil des Namens ist:


Ihre Migrationsdatei (beachten Sie die :id => false ; dies verhindert die Erstellung eines Primärschlüssels):

Schiene 3

class CreateRestaurantsUsers < ActiveRecord::Migration
  def self.up
    create_table :restaurants_users, :id => false do |t|
        t.references :restaurant
        t.references :user
    end
    add_index :restaurants_users, [:restaurant_id, :user_id]
    add_index :restaurants_users, :user_id
  end

  def self.down
    drop_table :restaurants_users
  end
end

Schienen 4

class CreateRestaurantsUsers < ActiveRecord::Migration
  def change
    create_table :restaurants_users, id: false do |t|
      t.belongs_to :restaurant
      t.belongs_to :user
    end
  end
end

t.belongs_to werden automatisch die erforderlichen Indizes erstellt. def change erkennt automatisch eine Vorwärts- oder Rückwärtsmigration, ohne dass eine Auf- oder Abwärtsbewegung erforderlich ist.

Schiene 5

create_join_table :restaurants, :users do |t|
  t.index [:restaurant_id, :user_id]
end

Hinweis: Es gibt auch eine Option für einen benutzerdefinierten Tabellennamen, der als Parameter an create_join_table übergeben werden kann. table_name . Von der docs

Standardmäßig ergibt sich der Name der Join-Tabelle aus der Vereinigung der ersten beiden Argumente für create_join_table in alphabetischer Reihenfolge Reihenfolge. Um den Namen der Tabelle anzupassen, geben Sie eine :table_name Option an:

44voto

Jan Klimo Punkte 4095

Die Antworten hier sind ziemlich veraltet. Ab Rails 4.0.2 verwenden Ihre Migrationen die create_join_table .

Um die Migration zu erstellen, führen Sie aus:

rails g migration CreateJoinTableRestaurantsUsers restaurant user

Dies führt zu folgendem Ergebnis:

class CreateJoinTableRestaurantsUsers < ActiveRecord::Migration
  def change
    create_join_table :restaurants, :users do |t|
      # t.index [:restaurant_id, :user_id]
      # t.index [:user_id, :restaurant_id]
    end
  end
end

Wenn Sie diese Spalten indizieren wollen, heben Sie die entsprechenden Zeilen auf, und schon kann es losgehen!

26voto

shacker Punkte 13440

Wenn Sie die Join-Tabelle erstellen, achten Sie sorgfältig darauf, dass die beiden Tabellen in alphabetische Reihenfolge in den Namen/Klassen der Migration. Dies kann leicht zum Problem werden, wenn Ihre Modellnamen ähnlich sind, z. B. "abc" und "abb". Wenn Sie Folgendes ausführen würden

rails g migration create_abc_abb_table

Ihre Beziehungen werden no funktionieren wie erwartet. Sie müssen verwenden

rails g migration create_abb_abc_table

stattdessen.

6voto

Mohit Jain Punkte 41795

Für HABTM-Beziehungen müssen Sie eine Join-Tabelle erstellen. Es gibt nur eine Join-Tabelle, und diese Tabelle sollte keine id-Spalte haben. Versuchen Sie diese Migration.

def self.up
  create_table :restaurants_users, :id => false do |t|
    t.integer :restaurant_id
    t.integer :user_id
  end
end

def self.down
  drop_table :restaurants_users
end

Sie müssen prüfen diese Beziehung Schienen Leitfaden Tutorials

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X