Creating the Polls table migration
Based on that, let's create our new migration, add_polls_table:
$ mix ecto.gen.migration add_polls_table
* creating priv/repo/migrations
* creating priv/repo/migrations/20171005161434_add_polls_table.exs
By default, that will give us a mostly blank file consisting of:
defmodule Vocial.Repo.Migrations.AddPollsTable do
use Ecto.Migration
def change do
end
end
This allows us to start putting together the definitions for our table! Let's take a look at what this file does:
First, we define a new module under Vocial.Repo.Migrations called AddPollsTable (remember that the gen.migration command we had used previously took add_polls_table as the only argument).
Next, we tell Ecto that this module should be using the macros and functions defined in the Ecto.Migration. In our IEx session, we can run h Ecto.Migration to learn more about the module and what it provides. The actual output is super-long so we won't include the whole thing, but it does provide a very handy example that we can use to piece together our migration:
defmodule MyRepo.Migrations.AddWeatherTable do
use Ecto.Migration
def change do
create table("weather") do
add :city, :string, size: 40
add :temp_lo, :integer
add :temp_hi, :integer
add :prcp, :float
timestamps()
end
end
end
This is pretty close to our initial skeleton, so let's take a look at what this file provides so that we can figure out how to properly write our migration files. The first thing in our migrations file is that a create table statement, where table is a function that takes in a string as the argument. That string is the name of the table that we want to create, so we’ll start creating our change statement in our add_polls_table migration:
def change do
create table("polls") do
end
end
Next, we need the statements that actually create the columns in our table. Looking at the example again, we see a bunch of add statements that take in two atoms as their arguments. The first argument is the name of the column that we want to add, and the second argument is the type of the column we want to add! There is also an additional optional third argument, which is a keyword list of options to the type (such as size, default, null, and so on). But what types are available to us? By default, Ecto supports the following types out of the box:
- :integer - A representation of any non-decimal numbers (like 3)
- :string - A representation of any types of string data (like banana)
- :text - A representation of larger blocks of strings (where, string may be the right choice for something simple like a title, :text might be the right choice for a big, long block of text, such as the content of a page; I'll skip the example of this one!)
- :float - A representation of decimal numbers (like 3.14)
- :datetime - A date and time representation of time
- :json - A representation of a JSON data structure (only available in some databases!)
You can also specify references as a part of types, but we'll get back into this later!
Okay, so, looking back at our original design for the Polls table, all that we need to specify is the title column, which should just be a string. There's also a helper to handle creation/insertion of the inserted_at and updated_at columns, which are timestamps that tell us when the Polls are created or updated. This helper is called timestamps()! That’s everything we need to know, so let's finally create our migration:
defmodule Vocial.Repo.Migrations.AddPollsTable do
use Ecto.Migration
def change do
create table("polls") do
add :title, :string
timestamps()
end
end
end
Now that we've filled out our file, let's run our actual migration! From our terminal, we'll run mix ecto.migrate:
$ mix ecto.migrate
[info] == Running Vocial.Repo.Migrations.AddPollsTable.change/0 forward
[info] create table polls
[info] == Migrated in 0.0s
We should have a table that looks something like this: