After adding a new attribute to the Post
model via a migration, I’d like to set a value of published_on
attribute of the Post
every time before saving a Post.
So, I added first this to the Posts
module:
def create_post(attrs \\ %{}) do
attrs = Map.merge(attrs, %{"published_on" => Date.utc_today() |> Date.to_string()})
%Post{}
|> Post.changeset(attrs)
|> Repo.insert()
end
But the existing controller tests fail: mix test test/blog_web/controllers/post_controller_test.exs
:
test update post renders errors when data is invalid (BlogWeb.PostControllerTest)
test/blog_web/controllers/post_controller_test.exs:64
** (Ecto.CastError) expected params to be a map with atoms or string keys, got a map with mixed keys: %{:content => "some body", :title => "some title", "published_on" => "2023-07-13"}
...
When changing the attrs map to have an atom key as follows:
def create_post(attrs \\ %{}) do
attrs = Map.merge(attrs, %{published_on: Date.utc_today() |> Date.to_string()})
%Post{}
|> Post.changeset(attrs)
|> Repo.insert()
end
it fails again with another error:
1) test update post renders errors when data is invalid (BlogWeb.PostControllerTest)
test/blog_web/controllers/post_controller_test.exs:64
** (Ecto.CastError) expected params to be a map with atoms or string keys, got a map with mixed keys: %{:published_on => "2023-07-13", "content" => nil, "title" => nil}
...
The `Post#changeset/2 looks like that:
def changeset(post, attrs) do
post
|> cast(attrs, [:title, :content, :published_on])
|> validate_required([:title, :content])
end
What’s wrong with that? Thank you.