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.
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.
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.
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
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
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