elixir-waffle / waffle_ecto

Waffle.Ecto provides an integration with Waffle and Ecto
https://hexdocs.pm/waffle_ecto
112 stars 30 forks source link

field updated_at waffle.Ecto.type in a embed schema #19

Open mrdotb opened 4 years ago

mrdotb commented 4 years ago

Hello,

When I write some tests I found a weird behavior from waffle_ecto The updated_at type return from insert differ from select. (NaiveDateTime to String) I did an example with phoenix since it happen when the data is inserted in postgres.

Basically I got a embeds_many who use Waffle.Ecto.Schema

defmodule Raven.Post do
  use Ecto.Schema
  import Ecto.Changeset

  schema "posts" do
    field :title, :string
    embeds_many :media, Raven.Media
  end

  def changeset(post, attrs) do
    post
    |> cast(attrs, ~w(title)a)
    |> cast_embed(:media, with: &Raven.Media.changeset/2)
  end
end

defmodule Raven.Media do
  use Ecto.Schema
  use Waffle.Ecto.Schema
  import Ecto.Changeset

  alias Raven.Uploaders.Media

  @primary_key false
  embedded_schema do
    field :src, Media.Type
    field :alt, :string
  end

  @doc false
  def changeset(media, attrs) do
    media
    |> cast(attrs, ~w(alt)a)
    |> cast_attachments(attrs, ~w(src)a)
  end
end

# I omit some code clone the example repo to get all

test "datetime not parsed" do
  upload = build_upload(@img)
  attrs = %{
    title: "Some title",
    media: [%{
      alt: "Some alt",
      src: upload
    },
    %{
      alt: "Some alt",
      src: upload
    }]
  }
  assert {:ok, post} = App.create_post(attrs)
  assert App.list_posts() == [post]
end

In the test result the updated_at field in the embeds_many is a NaiveDateTime on insert and a String on select Is this behavior expected ? (since it's stored in text format and not timestamp)

     left:  [
              %Raven.Post{
                __meta__: #Ecto.Schema.Metadata<:loaded, "posts">,
                id: 16,
                media: [
                  %Raven.Media{alt: "Some alt", src: %{file_name: "pixel.png", updated_at: "2020-06-15T16:48:58"}},
                  %Raven.Media{alt: "Some alt", src: %{file_name: "pixel.png", updated_at: "2020-06-15T16:48:58"}}
                ],
                title: "Some title"
              }
            ]
     right: [
              %Raven.Post{
                __meta__: #Ecto.Schema.Metadata<:loaded, "posts">,
                id: 16,
                media: [
                  %Raven.Media{alt: "Some alt", src: %{file_name: "pixel.png", updated_at: ~N[2020-06-15 16:48:58]}},
                  %Raven.Media{alt: "Some alt", src: %{file_name: "pixel.png", updated_at: ~N[2020-06-15 16:48:58]}}
                ],
                title: "Some title"
              }
            ]
     stacktrace:
       test/raven/app_test.exs:41: (test)

Thanks for your time.

achempion commented 4 years ago

Hi, thank your for reporting this issue and providing an example.

updated_at attribute should be the NaiveDateTime everywhere, I'll look into your repo.

mrdotb commented 4 years ago

Hello, did you have the time to check ? I can dive in ?

achempion commented 4 years ago

@mrdotb PR is welcome

Faymir commented 2 years ago

Hello. Is there any news about the correction of this bug?

timadevelop commented 1 year ago

@mrdotb @Faymir I made a PR, but if you need to fix this asap - you can write your own version of Waffle.Ecto.Definition that would implement embed_as/1 to return :dump value.

Honestly, it's quite sad that things like this bug are not being fixed in the elixir community for years... I wonder why. Because nobody stores filenames inside embeds? Maybe nobody uses this in production? Or everyone's using another lib for file uploading?

mrdotb commented 1 year ago

I guess not much people use it as embed. Glad you found the root cause. I tried a bit and I ended up not using waffle_ecto and roll my own embedded schema.