Ecto: Difference between cast_assoc and put_assoc, and how to create an assoc

Created on 7 Jul 2016  路  2Comments  路  Source: elixir-ecto/ecto

Had a question about creating associations. I have this code:

    changeset = changeset(%Note{}, params)
    with {:ok, note} <- Tome.Repo.insert(changeset) do
      Tome.Project.parse(note.content) # Returns a list of %Project{} structs.
      |> Enum.each(fn(project) ->
        project
        |> Ecto.Changeset.change
        |> Ecto.Changeset.put_assoc(:user, note.user)
        |> Tome.Repo.insert
      end)

      {:ok, note}
    end

And I keep getting the error:

** (UndefinedFunctionError) function Ecto.Association.NotLoaded.__changeset__/0 is undefined or private

I've also tried preloading the user on the note and on the project, but the same results happen.

I've also tried using cast_assoc.

It's difficult to figure out from the documentation what the difference between cast_assoc and put_assoc is. There are many examples of how to load assocs, but I couldn't find an example of how to create associations.

What is the best way to associate these two "records"?

Most helpful comment

To answer your question, you use cast_assoc when you want to cast external parameters, like the ones from a form, into an asociation. You use put_assoc when you already have an association struct.

All 2 comments

You didn't post the full stacktrace so I assume the error is happening here:

        |> Ecto.Changeset.put_assoc(:user, note.user)

And it means the association was not loaded. You have figured out so far but what happens when you guarantee the user was loaded? What is the new error?

Also, please don't use the issues tracker for questions, prefer the mailing list for those. :)

To answer your question, you use cast_assoc when you want to cast external parameters, like the ones from a form, into an asociation. You use put_assoc when you already have an association struct.

Was this page helpful?
0 / 5 - 0 ratings