W tym przykładzie tworzę user
bez profile
, a później tworzę profile
dla tego użytkownika. Próbowałem użyć kompilacji ze has_one
skojarzeniem, ale to wybuchło. Jedynym sposobem, w jaki widzę, że to działa, jest użycie has_many
. user
Ma mieć tylko co najwyżej jeden profile
.
Próbowałem tego. Mam:
class User < ActiveRecord::Base
has_one :profile
end
class Profile < ActiveRecord::Base
belongs_to :user
end
Ale kiedy robię:
user.build_profile
Wyskakuje mi błąd:
ActiveRecord::StatementInvalid: Mysql::Error: Unknown column 'profiles.user_id' in 'where clause': SELECT * FROM `profiles` WHERE (`profiles`.user_id = 4) LIMIT 1
Czy istnieje sposób w szynach na 0 lub 1 skojarzenie?
Odpowiedzi:
build
Podpis metoda jest różna dlahas_one
ihas_many
stowarzyszenia.Składnia kompilacji dla
has_many
asocjacji:Składnia kompilacji dla
has_one
asocjacji:Przeczytaj dokumentację
has_one
stowarzyszenia, aby uzyskać więcej informacji.źródło
user.build_profile
do edycjiuser.build_profile if user.profile.nil?
i jeśli chcesz zbudować profil podczas tworzenia użytkownika, wpiszaccepts_nested_attributes_for :profile
to w Model użytkownika. iw formularzu, który użytkownik jest tworzony, napisz<%= f.simple_fields_for :profile do |p| %>
to i kontynuuj.build_<association>
) jest dość dziwnym i nieoczekiwanym zachowaniem w Railsach, o wiele więcej ludzi szuka tej odpowiedzi niż odpowiedzi na pytania, jeśli wiesz, o co mi chodzi.Przyjrzyj się dokładnie komunikatowi o błędzie. Mówi ci, że nie masz wymaganej kolumny
user_id
w tabeli profilu . Ustalenie relacji w modelu to tylko część odpowiedzi.Musisz także utworzyć migrację, która doda
user_id
kolumnę do tabeli profili. Railsy tego oczekują, a jeśli tak nie jest, nie możesz uzyskać dostępu do profilu.Więcej informacji znajdziesz pod tym linkiem:
Podstawy asocjacji
źródło
rails g model profile user:references:index address:string bio:text
.W zależności od przypadku użycia może być wygodne zawinięcie metody i automatyczne utworzenie asocjacji, gdy nie zostanie znaleziona.
teraz wywołanie
#profile
metody zwróci skojarzony profil lub utworzy nową instancję.źródło: Kiedy małpa łata metodę, czy możesz wywołać zastąpioną metodę z nowej implementacji?
źródło
def profile; super || build_profile; end
.Powinien to być plik
has_one
. Jeślibuild
nie działa, możesz po prostu użyćnew
:jest taki sam jak
źródło