dodawanie skojarzeń do istniejących modeli

Zastanawiam się, jak Mogę dodać skojarzenia do moich modeli. Załóżmy, że generuję dwa modele

rails generate model User
rails generate model Car

Teraz chcę dodać asocjację, aby modele nabrały formy

class User < ActiveRecord::Base
  has_many :cars
end
class Car < ActiveRecord::Base
  belongs_to :user
end

Pytanie brzmi: jak zastosować tę modyfikację przez migracje, aby uzyskać tabelę cars_users w bazie danych? Planuję użyć tej tabeli w moim kodzie.

Author: Andrew, 2013-03-13

4 answers

belongs_to Asocjacja oczekuje kolumny association_id w odpowiadającej jej tabeli. Ponieważ cars belongs_to user, tabela cars powinna mieć kolumnę user_id. Można to osiągnąć na 2 sposoby.

Najpierw możesz wygenerować kolumnę podczas tworzenia modelu

rails g model car user_id:references

Lub po prostu dodaj user_id po utworzeniu modelu, jak odpowiedź Richarda Browna. Uważaj, że jeśli użyjesz integer zamiast references, będziesz musiał utworzyć indeks samodzielnie.

rails g migration add_user_id_to_cars user_id:integer

Następnie w wygenerowanym migracja, dodaj

add_index :cars, :user_id

Aktualizacja:

Jak wspomniał Joseph w komentarzach, potrzeba ręcznego dodawania indeksu została już rozwiązana w obecnej wersji Rails. Myślę, że został wprowadzony w Rails 4. Więcej o tym można przeczytać w official rails guide for migrations . Jego istotą jest uruchomienie następującego generatora

bin/rails g migration add_user_to_cars user:references

Utworzy migrację z linią podobną do

add_reference :cars, :user, index: true

To doda kolumnę user_id do tabeli samochodów i będzie również oznaczać tę kolumnę do indeksowania.

 64
Author: jvnill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-05 16:05:23

Podążając za wyjaśnieniem @jvnill w rails 4 (i może również w rails 3.2) możesz to zrobić tak samo (unikając części id i pamiętając dokładne konwencje):

rails g migration AddUserToCar user:references

, który utworzy następującą migrację, dbając zarówno o dodanie kolumny, jak i indeksu ze wszystkimi poprawnymi konwencjami:

class AddUserToCar < ActiveRecord::Migration
  def change
    add_reference :cars, :user, index: true
  end
end

Na końcu jak zawsze Uruchom migrację:

rake db:migrate

Wyświetl schema.rb, aby wyświetlić nową kolumnę index i user_id.

 16
Author: SimonW,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-31 06:24:33

Wygenerowanie migracji w celu utworzenia asocjacji:

rails g migration AddUserIdToCars user_id:integer
rake db:migrate
 7
Author: Richard Brown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-13 12:57:52

Plik migracji:

class Createuser < ActiveRecord::Migration[5.0]
  def change
    create_table :users do |t|
      t.string :name
    end

    create_table :cars do |t|
      t.belongs_to :user, index: true
      t.varchar(255) :model
      t.varchar(255) :color
    end
  end
end
 0
Author: vinoth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-25 13:02:18