Używanie build with a ma jedno skojarzenie w rails

W tym przykładzie tworzę user z no profile, a następnie utwórz profile dla tego użytkownika. Próbowałem użyć build z has_one skojarzenia, ale to wybuchło. Jedynym sposobem, w jaki to działa, jest użycie has_many. user powinien 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 to zrobię:

user.build_profile 

Dostaję 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 w rails istnieje sposób na skojarzenie 0 LUB 1?

Author: omnikron, 2010-03-18

4 answers

Sygnatura metody build jest inna dla asocjacji has_one i has_many.

class User < ActiveRecord::Base
  has_one :profile
  has_many :messages
end

Składnia budowania dla has_many Asocjacja:

user.messages.build

Składnia budowania dla has_one Asocjacja:

user.build_profile  # this will work

user.profile.build  # this will throw error
Więcej informacji można znaleźć w dokumentacji Stowarzyszenia

has_one .

 334
Author: Harish Shetty,
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
2012-03-04 06:03:37

Przyjrzyj się dobrze komunikatowi o błędzie. Oznacza to, że nie masz wymaganej kolumny user_id w tabeli profile . Ustawienie relacji w modelu jest tylko częścią odpowiedzi.

Musisz również utworzyć migrację, która doda kolumnę user_id do tabeli profilu. Rails spodziewa się, że to tam będzie, a jeśli tak nie jest, nie możesz uzyskać dostępu do profilu.

Aby uzyskać więcej informacji, proszę spojrzeć na ten link:

Podstawy Asocjacji

 16
Author: sosborn,
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
2016-05-28 17:23:13

W zależności od przypadku użycia, wygodne może być zawinięcie metody i automatyczne zbudowanie asocjacji, gdy nie zostanie znaleziona.

old_profile = instance_method(:profile)
define_method(:profile) do
  old_profile.bind(self).call || build_profile
end

Teraz wywołanie metody #profile zwróci powiązany profil lub zbuduje nową instancję.

Źródło: kiedy monkey patchuje metodę, czy można wywołać metodę overridden z nowej implementacji?

 0
Author: Shiyason,
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-05-23 12:10:32

Powinno być has_one. Jeśli build nie działa, możesz po prostu użyć new:

ModelName.new( :owner => @owner )

Jest tym samym co

@owner.model_names.build
 -13
Author: Karl,
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
2010-03-18 20:45:13