ruby on rails migrations Rails ha_and_belongs_to_many migration




ruby rails scope (4)

Ho due modelli di restaurant e user che voglio eseguire una relazione has_and_belongs_to_many.

Sono già entrato nei file del modello e has_and_belongs_to_many :restaurants aggiunto has_and_belongs_to_many :restaurants e has_and_belongs_to_many :users

Suppongo che a questo punto dovrei essere in grado di fare qualcosa come con Rails 3:

rails generate migration ....

ma tutto ciò che ho provato sembra fallire. Sono sicuro che questo è qualcosa di veramente semplice. Sono nuovo per i binari, quindi sto ancora imparando.


Quando si crea la tabella di join, prestare particolare attenzione al requisito che le due tabelle debbano essere elencate in ordine alfabetico nel nome / classe della migrazione. Questo può facilmente morderti se i nomi dei tuoi modelli sono simili, ad esempio "abc" e "abb". Se dovessi correre

rails g migration create_abc_abb_table

Le tue relazioni non funzioneranno come previsto. Devi usare

rails g migration create_abb_abc_table

anziché.


Per le relazioni HABTM, è necessario creare una tabella di join. C'è solo join table e quella tabella non dovrebbe avere una colonna id. Prova questa migrazione.

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

È necessario controllare questo tutorial sulle guide delle guide di relazione


È necessario aggiungere una tabella di join separata con solo restaurant_id e user_id (senza chiave primaria), in ordine alfabetico .

Per prima cosa esegui le tue migrazioni, quindi modifica il file di migrazione generato.

Rails 3

rails g migration create_restaurants_users_table

Rotaie 4 :

rails g migration create_restaurants_users

Rails 5

rails g migration CreateJoinTableRestaurantUser restaurants users

Dai docs :

C'è anche un generatore che produrrà tabelle di join se JoinTable fa parte del nome:

Il tuo file di migrazione (annota :id => false ; è ciò che impedisce la creazione di una chiave primaria):

Rails 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

Rotaie 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 creerà automaticamente gli indici necessari. def change difetto rileva automaticamente una migrazione in avanti o di rollback, senza necessità di andare su / giù.

Rails 5

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

Nota: esiste anche un'opzione per un nome tabella personalizzato che può essere passato come parametro a create_join_table chiamato table_name . Dai docs

Per impostazione predefinita, il nome della tabella join deriva dall'unione dei primi due argomenti forniti per create_join_table, in ordine alfabetico. Per personalizzare il nome della tabella, fornire un'opzione: table_name:


Le risposte qui sono piuttosto datate. A partire da Rails 4.0.2, le tue migrazioni fanno uso di create_join_table .

Per creare la migrazione, esegui:

rails g migration CreateJoinTableRestaurantsUsers restaurant user

Questo genererà quanto segue:

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

Se vuoi indicizzare queste colonne, decommenta le rispettive linee e sei a posto!







has-and-belongs-to-many