Why would an Ecto migration have a text type but the schema doesn’t?
When I try to seed my DB, I get an error
** (Ecto.ChangeError) value `%WolfBlog.Blog.Post{__meta__: #Ecto.Schema.Metadata<:built,
"posts">, body: "Absinthe can really make working with Phoenix and Graphql much easier.
The big advantage is that you can also test the code.", id: nil, inserted_at: nil, title: nil,
updated_at: nil}` for `WolfBlog.Blog.Post.body` in `insert` does not match type :string
My post schema
defmodule WolfBlog.Blog.Post do
use Ecto.Schema
import Ecto.Changeset
alias WolfBlog.Blog.Post
schema "posts" do
field :body, :string
field :title, :string
timestamps()
end
@doc false
def changeset(%Post{} = post, attrs) do
post
|> cast(attrs, [:title, :body])
|> validate_required([:title, :body])
|> unique_constraint(:title)
end
end
My migration
defmodule WolfBlog.Repo.Migrations.CreatePosts do
use Ecto.Migration
def change do
create table(:posts) do
add :title, :string
add :body, :string
timestamps()
end
create unique_index(:posts, [:title])
end
end
My alter table migration to add text primitive to body
defmodule WolfBlog.Repo.Migrations.BodyStringToBodyText do
use Ecto.Migration
def change do
alter table(:posts) do # alter will modify the posts table
modify :body, :text # modifies the body column from string to text
end
end
end
How can I make the body field from the schema have a text type?
Yes the full code is part of my series on absinthe and is open source
Seeder
defmodule WolfBlog.Seeder do
def power_up() do
alias WolfBlog.Blog.Post
alias WolfBlog.Repo
absinthe_title = %Post{title: "Absinthe is great"}
absinthe_body = %Post{body: "Absinthe can really make working with Phoenix and Graphql much easier.The big advantage is that you can also test the code."}
_article = %Post{title: absinthe_title , body: absinthe_body} |> Repo.insert() #Bring the values from title and body and create
# an article that get's added to the DB
:ok
end
end
absinthe_title = %Post{title: "Absinthe is great"}
absinthe_body = %Post{body: "Absinthe can really make working with Phoenix and Graphql much easier.The big advantage is that you can also test the code."}
you’re creating two different %Post{}, one with only the body and the other with only the title. try doing:
The migration tells the database how to store data.
The schema type describes how to convert elixir data types to something the database understands.
They are only loosely related in the sense, that the column type A is a requirement for a given schema type B to be able to convert elixir types.
The schema type :string does know how to convert elixir strings (aka binaries) into a column type of text or varchar or other “text like” column types.
defmodule WolfBlog.Seeder do
def power_up() do
alias WolfBlog.Blog.Post
alias WolfBlog.Repo
absinthe_title = "Absinthe is great"
absinthe_body = "Absinthe can really make working with Phoenix and Graphql much easier.The big advantage is that you can also test the code."
_article = %Post{title: absinthe_title , body: absinthe_body} |> Repo.insert() #Bring the values from title and body and create
# an article that get's added to the DB
:ok
end
end
Thanks i know that part, but somehow after I written a lot of English today in a very long article, I couldn’t see that mistake Thanks again for the right direction.
The differentiation exists because databases have multiple string types for storing, including a limited string type (string in ecto) and longer type (text in ecto). Basically it gets back to the desires of DBAs striving for optimizing databases and only storing as much as you need. Most of it doesn’t matter until you get to scale or hire a proper DBA. But when speed matters it becomes important.