2017-02-02 1 views
0

У меня есть столы, Category и Subcategory.Как я могу вставить идентификатор внешнего ключа с помощью канала?

Category имеет много subcategories и Subcategory относится к category.

В моем канале handle_in есть функция для вставки подкатегории, как показано ниже.

def handle_in("create:subcategory", %{"name" => name, "category_id" => category_id}, socket) do 
changeset = Subcategory.changeset(%Subcategory{name: name, category_id: category_id}) 
|>Repo.insert 

subcategories = from(p in Pos8.Subcategory, select: map(p, [:id, :name, :category_id])) |> Repo.all 
response = %{subcategories: subcategories} 

    broadcast! socket, "subcategories:updated", response 

{:noreply, socket} 
end 

Поэтому в основном то, что я хочу сделать, это создать подкатегорию с name и category_id мимоходом. Но это вызывает ошибку, которая Myapp.Subcategory.category_id in insert does not match type :id (ecto) lib/ecto/repo/schema.ex:691: Ecto.Repo.Schema.dump_field!/6 (ecto) lib/ecto/repo/schema.ex:700: anonymous fn/6 in Ecto.Repo.Schema.dump_fields!/5

Как я могу вставить category_id при создании subcategory?

Заранее спасибо ..

ответ

1

Если вы должны были сделать тест, то можно заметить, что category_id является строкой. Это нормально, когда вы пытаетесь найти значение значение в базе данных, используя что-то вроде Repo.get/3, но, к сожалению, при попытке вставить исходное значение не будет ничего.

Однако вы должны просто сделать что-то вроде String.to_integer(category_id), и вы сможете вставить его просто отлично.

Так что ваша окончательная вставка строка будет выглядеть

changeset = 
    Subcategory.changeset(%Subcategory{name: name, 
            category_id: String.to_integer(category_id)}) 
    |> Repo.insert() 

Как @Dogbert указывает в комментариях, вы можете просто позволить функцию сделки с набора изменений преобразования.

changeset = 
    Subcategory.changeset(%Subcategory{}, %{name: name, category_id: category_id}) 
    |> Repo.insert() 

Это полезно для работы не только по целочисленным типам.

+0

спасибо, он работает! –

+0

Или пусть 'changeset/2' обрабатывает преобразование:' Subcategory.changeset (% Subcategory {},% {name: name, category_id: category_id}) '. – Dogbert

+0

Как @Dogbert указывает, позволяя сменой изменений справиться с этим лучше. Тем более, что вы не всегда можете иметь дело с целыми идентификаторами в будущем. –

0

Это может работать:

import Ecto.Changeset 
parent = Repo.get!(Category, category_id) 
subcategory = cast(%Subcategory{}, %{name: name}) 
       |> put_assoc(:category, parent) 
       |> Repo.insert! 
+0

К сожалению, это вызовет базу данных дважды. Однажды, чтобы захватить родителя, и снова, чтобы вставить запись. –

Смежные вопросы