Próbuję wstawić strukturę faktury wraz z powiązanymi elementami faktury. Mogę wstawić dane do faktury i zadzwonić do anonimowej funkcji, aby zweryfikować, odlać i wstawić każdy przedmiot. Ponieważ insert/2 nie generuje zwrotu, w jaki sposób mogę uzyskać wartość invoice_id dla produktów, gdy wciąż można wycofać całą transakcję, jeśli jeden element nie przejdzie sprawdzania lub wstawiania?Wstawianie powiązanych modeli w Ecto
Mam umieścić kod w moim repo, to jest tutaj:
def insertassoc(params) do
Repo.transaction(fn ->
i = Invoice.changeset(params["data"], :create)
if i.valid? do
Repo.insert(i)
else
Repo.rollback(i.errors)
end
insert_include = fn k ->
c = InvoiceItem.changeset(k, :create)
if c.valid? do
Repo.insert(c)
else
Repo.rollback(c.errors)
end
end
for include <- params["includes"] do
insert_include.(Map.merge(include, %{"invoice_id" => ????}))
end
end)
end
i tutaj jest, jak go używać z mojego kontrolera:
def create(conn, params) do
case InvoiceRepo.insertassoc(params) do
{:ok, x} ->
json conn, Map.merge(params, %{"message" => "OK"})
{:error, x} ->
json conn |> put_status(400), Map.merge(params, %{"message"
=> "Error"})
end
end
Nie ma wiele do góry do tej pory przykłady z Ecto, więc przepraszam, jeśli to są pytania noob ;-). Ktoś ma pomysł? Próbowałem wstawić fakturę wstawić do prywatnej funkcji i użyć bloku przypadku, aby ustalić, czy główna transakcja powinna zostać wycofana, ale nie mogłem również wymyślić, jak odzyskać z tego identyfikator faktury.
Dziękuję, to jest o wiele bardziej eleganckie. BTW, dla tych, którzy będą z tego korzystać, oto jak poradziłem sobie z błędami, aby je zakodować w JSON: 'errors = Enum.map (items, & (& 1.errors)) |> Enum.into ([invoice.errors ]) |> Enum.map (& (Enum.into (& 1,% {}))) {: errors, errors} ' –
Interfejs API zmienił się teraz, aby' Repo.insert' zastąpić 'Repo. wstaw! ', aby zwrócić model lub zgłosić błąd w transakcji. – Arrel
Co więcej, Ecto obsługuje teraz również 'put_assoc', który pozwala na zmianę schematu nadrzędnego wraz z jego dziećmi, co znacznie uprościłoby powyższy kod! –