Adding Fields to an Ecto Model in Phoenix
I recently needed to add some fields to an Ecto model that I had generated with mix phoenix.gen.html [...]
, and to use the new fields in a Phoenix app. Google did not immediately serve up a simple tutorial, so here it is!
This assumes you have generated a new Phoenix app and then generated a Users model, like so:
If you need more information on any of the steps, they are covered in detail in Phoenix and Ecto from mix new to Heroku, or feel free to ask in the comments below.
Before moving on, visit http://localhost:4000/users and make sure you can add, edit, and delete a user.
After discovering that I needed to add some fields to the User model, I checked to see if there was something like rails generate migration NAME [field[:type]...]
.
Not quite (yet?), but there is mix ecto.gen.migration
which will generate a skeleton for you to fill in. You can read about it in the Phoenix Mix Tasks docs docs, or in the Ecto docs.
Note: If you search for something related to Phoenix and end up at a URL that contains a version number such as /v0.10.0/
, be sure to delete that bit of the URL and reload the page so that you are looking at the latest version of the docs.
Generate a Migration
Let’s generate a migration to add fields to our User model.
If we open the [datetime]_add_fields_to_users.exs
file it says it created, we’ll see this:
It’s up to us to tell it what needs to be changed. We can get a hint by looking at the other file in the migrations directory, named [datetime]_create_user.exs
:
We want essentially the same thing with alter table
instead of create
, and with our new fields and types. Let’s update the add_fields_to_users migration with this:
Run the Migration
Before we run the migration, let’s have a look at the database in the Postgres psql
console:
Now we can run the migration…
… and have another look at the users table:
What if we made a mistake? If so, we can roll back with:
If you now look at the database table, the additional fields will be gone. (If you did the rollback, re-run the migration to put the fields back in place.)
Update Phoenix App
Now that our new fields exist in the database, let’s look at what’s needed to use them in our Phoenix app.
These aren’t fields that will need to be edited directly, (they will be coming from another application after the user grants us access to their data via OAuth,) but we can display the user_id on the ‘show’ page.
Let’s edit the template at web/templates/user/show.html.eex
:
If we add a user and then click the ‘Show’ link, we’ll get an error. We need to add the user_id to the model. While we’re at it, let’s add the other fields and make them all optional. In web/models/user.ex
:
(Note that if you do not add the new fields to either @required_fields
or @optional_fields
, they will be ignored when you attempt to update the database.)
Now, visiting http://localhost:4000/users, adding a user and clicking ‘Show’ will work – the User ID label will be displayed along with no value since the field is empty.
Next let’s simulate adding a user after they return from the OAuth flow and have granted us access to their data. In reality there will be other libraries and a separate controller involved, but we’ll just add a new function to the page controller.
In web/page_controller.ex
, add this above the current index
function:
This must be added above the current index
method due to the pattern match. This function definition will match on a request that contains ‘test’ as a parameter. (The underscore means that we don’t care what the value is, just that it is present.) If there is no ‘test’ parameter, then it will continue on and run the original index
function that does not care about the parameters.
Now if you visit http://localhost:4000/?test you will get routed to this function instead of the default index function, and the console log will show:
You can see that values for all of the fields are filled in, and there were no errors. If you return to http://localhost:4000/users and click ‘Show’ for the last one in the list, you should see that user id displayed:
The code for this example is available at https://github.com/wsmoak/my_app_726605/tree/20150727
Copyright 2015 Wendy Smoak - This post first appeared on http://wsmoak.github.io and is licensed CC BY-NC.