If you're like me, you might be new to the Phoenix framework. Maybe you're building a blog and you want to use a text
column for blog post content. You hastily glance though Ecto's built-in types, but you don't see a text
type. You see string
, but that turns into a varchar
column after you run your migration. What givesโcan you not create text
columns with Phoenix & Ecto?
Here's the good news: you can create text
columns with Phoenix. It's actually super simple. Let's generate a blog post schema using Mix:
mix phx.gen.schema BlogPost blog_post title:string content:text
See where it says content:text
? That's all there is to it. When you run mix ecto.migrate
, the content
column will have a type of text
. However, it's worth exploring what this command actually does.
Exploring the generated files
When we run the mix phx.gen.schema
command, Phoenix generates two files:
- A migration file located at
priv/repo/migrations/{datestring}_create_blog_posts.ex
- A schema file located at
lib/{app_name}/blog_post.ex
Let's first look at the migration file:
defmodule Backend.Repo.Migrations.CreateBlogPost do
use Ecto.Migration
def change do
create table(:blog_post) do
add :title, :string
add :content, :text
timestamps()
end
end
end
This looks the way that we'd expect: we have a content
column with a type of text
. But text
isn't a built-in Ecto type, so how does this work?
As user al2o3cr points out in the Elixir Forum: Ecto migrations will pass along any type that it doesn't recognize as-is (see Ecto's source code).
Now let's look at the schema file at lib/{app_name}/blog_post.ex
:
defmodule Backend.BlogPost do
use Ecto.Schema
import Ecto.Changeset
schema "blog_post" do
field :content, :string
field :title, :string
timestamps()
end
# Other code...
end
Hold on, doesn't it say field :content, :string
in the schema
block? Why is it :string
and not :text
? What's going on here?
As the Phoenix Docs mention:
Ecto schemas are responsible for mapping Elixir values to external data sources, as well as mapping external data back into Elixir data structures.
The schema file is primarily concerned with the Elixir data type of the content
column and mapping it to the database. It doesn't need to be concerned with the column type: that's already stored in the database once you've run your migration using mix ecto.migrate
.
I hope this helps clarify what's going on under the hood as you use text
columns in your own Phoenix apps. Special thank you to Nick Ciolpan for writing this post that helped me work through this problem.
If this saved you some time, please leave a like or a comment so I know it was helpful!
Top comments (2)
Great job writing this!
Hey thanks Nick! ๐