Ecto.Type with :source

Hello,
I am in process of learning elixir phoenix and ecto, so far I love it.

Though, I am having hard time combining Ecto.Type and :source field together and i am not even sure if that is possible.

Let’s assume the following simple schema:

schema "content_articles" do
    field :title, :string
    field :body, :string
    field :formatted_body, :string, [source: :body ]
    field :status, :string
    timestamps()
end

Executing query with this schema, it outputs something like

SELECT c0."id", c0."title", c0."body", c0."body", c0."status", c0."inserted_at", c0."updated_at", c0."id" FROM "content_articles" AS c0 WHERE (c0."id" = $1)

So body column is referenced twice. So far so good.

I am now trying to replace :string with MyCustomType which implements the Ecto.Type for the formatted_body field:

#aliases here
schema "content_articles" do
    field :title, :string
    field :body, :string
    field :formatted_body, MyCustomType , [source: :body ]
    field :status, :string
    timestamps()
end

gives the following error:
** (Postgrex.Error) ERROR 42703 (undefined_column): column c0.formatted_body does not exist

What am I missing? Should maybe map the formatted_body to body within the load callback?

A quick look at the Ecto.Schema source code doesn’t reveal any obvious difference in how it handles built-in types versus custom types.

Can you try to execute MySchemaModule.__schema__(:fields) and see, in both cases, if there’s anything obviously different?

And then MySchemaModule.__schema__(:type, :formatted_body) and MySchemaModule.__schema__(:source_type, :body)

1 Like

Hello kip and thanks for suggestion.
Everything looks OK in my eyes after executing the above.
In the second schema case, where :formated_body is of type MyCustomType the MySchemaModule.__schema__(:type, :formatted_body) reports back MyCustomType and the MySchemaModule.__schema__(:source_type, :body) reports back :string

While typing this, I was playing with your commands, changing schema “on-the-fly”. I noticed that these changes don’t get evaluated without a server restart. Magically, after server restart, all errors gone and the behaviour is as expected with :formatted_body to be populated correctly from :body and through the MyCustomType implementation.

Your commands there, pointed me to the right solution :slight_smile:

1 Like

A schema is evaluated at compile time, not runtime. So the module needs to be compiled again if you change the schema. Phoenix should do that automatically for you I believe, it perhaps in those case, for whatever reason, it didn’t. Anyway, Glad it’s all working for you now.

2 Likes