cast_assoc
służy do „szarego związane modelu” i może być używany tylko z has_one
i has_many
. Relacja belongs_to
definiuje obcy identyfikator w modelu, w którym jest wywoływany. has_many
i has_one
polegać na "innym" obiekcie posiadającym klucz obcy.
Jeśli tworzysz obiekt, który ma wiele innych obiektów, warto sprawdzić je wszystkie, jeśli są prawidłowe. cast_assoc
wywoła cast
w odpowiednich modułach.
Twój użytkownik może mieć wiele subskrypcji (prawdopodobnie zgaduję tutaj), więc nie ma sensu tworzyć użytkownika podczas tworzenia subskrypcji i sprawdzać, czy użytkownik jest ważny przez cast_assoc
. Zwykle w tym przypadku użytkownik będzie już istnieć w bazie danych.
W twoim przypadku chcesz tylko sprawdzić, czy wiąże modelu istnieje w gipsie, więc należy używać:
|> assoc_constraint(:user)
ta nie sprawdza użytkownika, ale sprawdza, czy dana user_id
istnieje w bazie danych. Teraz, gdy chcesz zaktualizować subskrypcję dla użytkownika można to zrobić:
user = Repo.get(User, id)
subscription = Ecto.build_assoc(user, :subscriptions, other_fields_as_map)
Uwaga wymaga has_one
lub has_many
na modelu użytkownika.
Albo można po prostu zaktualizować identyfikator użytkownika, jak próbował wcześniej:
Rebirth.Subscription.update_user(subscription, %{user_id: 1})
i tym razem sprawdzi bazę danych, jeśli id dany użytkownik istnieje, ale nie będzie w stanie przejść całą obiekt użytkownika tutaj.
A jeśli chcesz zaktualizować powiązanego użytkownika, będziesz musiał zrobić to jawnie w dwóch krokach. a) uzyskać użytkownika, b) zaktualizować użytkownika za pomocą zestawu zmian zdefiniowanego w jego module.
Ostatnia uwaga, jeśli nie dokonujesz oddzielnego sprawdzania poprawności dla aktualizacji użytkowników (i nie sądzę, że powinieneś w tym scenariuszu), dobrze byłoby zmienić nazwę funkcji z update_user
na changeset
. Ten sam zestaw zmian może być używany do tworzenia i aktualizowania modeli.
Obecnie doświadczam tego samego problemu.:/ –
Nie znalazłem jeszcze sposobu, aby to naprawić, ale kopiąc wokół, izolowałem problem do 'Ecto.Changeset.cast_relation/4'. W szczególności 'Map.get (types, key)'. Stowarzyszenie nie jest jednym z modeli "typów". –
Cóż, moje "to środek nocy i jestem tym zmęczony", należy usunąć 'cast_assoc' i dodać' user_id' do listy wymaganych parametrów. To przyzwoite tymczasowe obejście. –