I’ve never felt too clear on the right way to build associations.
Creating a new post for a pre-existing Author. I would like the author struct to be available on the changeset for later logic/validation.
Question:
What is the correct way to implement associate_with(changeset, author)
?
def create_post(author, params) do
%Post{}
|> Post.changeset(params)
|> associate_with(author)
|> ensure_author_has_rights()
|> other_validation_that_may_need_author()
|> Repo.insert()
end
# in this contrived example, I am aware that I could
# simply pass in the author as an argument :)
def ensure_author_has_rights(changeset) do
author = changeset.changes.author
case author.type do
"normal_user" -> changeset
"admin_user" -> add_error(changeset, :author_id, "invalid author")
end
end
The problem with put_assoc
:
def create_post(author, params) do
%Post{}
|> Post.changeset(params)
|> put_assoc(author)
This does achieve what I want:
def ensure_author_has_rights(changeset) do
author = apply_changes(changeset.changes.author)
So clearly the changeset seems to think I am updating the Author, which makes me think this isn’t the correct approach:
Ecto.changeset.changes{
author: #Ecto.Changeset<action: :update, changes: %{}, errors: [], data: #App.Accounts.Author<>, valid?: true>
}