2017-02-09 8 views
1

Я работаю над приложением Phoenix, это личная версия Evernote. У меня есть модель Book, что has_manyNote записей.Модель Phoenix с отношением has_many не обновляется без предварительной загрузки отношения

Это моя книга модель:

defmodule Notebook.Book do 
    use Notebook.Web, :model 

    schema "books" do 
    field :name, :string, default: "" 
    has_many :notes, Notebook.Note 
    belongs_to :user, Notebook.User 
    timestamps() 
    end 

    @doc """ 
    Book changeset. Name field required. 
    """ 
    def changeset(model, params \\ %{}) do 
    model 
    |> cast(params, [:name]) 
    |> validate_required(:name) 
    end 
end 

И у меня есть конечная точка обновления в моем контроллере:

def update(conn, %{"id" => id, "book" => book_params}) do 
    existing_book = Repo.get(Book, id) 
    changeset = Book.changeset(existing_book, book_params) 

    case Repo.insert(changeset) do 
    {:ok, book} -> 
     conn 
     |> put_status(:ok) 
     |> render("show.json", book: book) 

    {:error, changeset} -> 
     conn 
     |> put_status(:unprocessable_entity) 
     |> render("error.json", message: changeset.errors) 
    end 
end 

И тест:

test "with a valid jwt", %{conn: conn, jwt: jwt} do 
    book = insert(:book) 
    resp = conn 
    |> put_req_header("authorization", "Bearer: #{jwt}") 
    |> put(book_path(Endpoint, :update, book, book: %{name: "New Book"})) 
    |> json_response(:ok) 

    assert resp["data"]["book"]["name"] == "New Book" 
end 

Когда я запускаю мои тесты , Я получаю эту ошибку:

** (RuntimeError) attempting to cast or change association `notes` from `Notebook.Book` that was not loaded. Please preload your associations before manipulating them through changesets 

Параметры, которые я отправляю, являются только name. В этом я нашел related issue, но поскольку я не использую cast_assoc, я не думаю, что это применимо.

Я не могу понять, что я здесь делаю неправильно. Я понимаю (я думаю) о предзагрузке отношений в Ecto, но в этом случае я не обновляю зависимые записи Note, просто одно поле записи Book, поэтому мне не нужно предварительно загружать.

Весь репо - here.

ответ

1

Похоже, вы используете Repo.insert в способе update от BookController. Изменение этого на Repo.update должно исправить.

+0

Спасибо, сэр! Некоторое время я застрял на этом. –