Phoenix and Ecto with MongoDB
I saw (on @ElixirStatus) that the Ecto adapter for MongoDB was released, and wanted to try it out. Looking around, I found that while the adapter itself was in the hex repository, the PR that would let the Phoenix installer (the phoenix.new mix task) know about mongodb had not yet been merged. Let’s see how to try out someone else’s as-yet-unmerged changes!
UPDATE: As of 2015-09-06 PR 1161 was merged and this feature is available in Phoenix 1.0.2. Now mix phoenix.new my_project --database mongodb
will work with no need to build it yourself. Install the latest version and then skip down to Create A Project to try it out. (You’ll need to leave off the --dev
switch.)
NOTE: This involves using un-released code on master and a feature branch. If you’re interested in playing on the bleeding edge, follow me! If not, you may want to wait until this makes its way into a release.
Clone A Fork
There are [at least] two ways to go about this. One is to simply clone the other contributor’s fork and grab their branch directly. It looks like this:
Now we have Michał’s fork of the Phoenix Framework repository cloned locally in a directory called “phoenix-michalmuskala” * and we can work with it.
- (to avoid stepping on our own fork which is probably in a directory called “phoenix”)
Add A Remote
Another way is to add their repo as a remote to your own fork of Phoenix, and then apply their changes to a branch of your own.
First, make sure your master branch is up to date. See syncing a fork for more info. If you want to play on the bleeding edge, this is something you’ll get in the habit of doing daily:
Now if you check your fork on GitHub, it should say “This branch is even with phoenixframework:master”.
Now, add Michał’s fork as a remote
If you check with git remote -v
you should see it listed:
Now create a new local branch, and pull the changes from Michał’s branch into it. I’m using the same branch name, but it’s important to note that these are two completely separate branches in different git repositories.
Now you have the absolute latest Phoenix Framework code plus Michał’s changes.
Optionally, you can push your new branch to GitHub. I usually just type git push
and let it fail and tell me what to do. It says:
Now if you look at your branch you should see it say you are ahead of phoenixframework:master.
Verify the Version
However you decided to retrieve the code, change into that directory, and then into the installer subdirectory.
In the original Phoenix on the Bleeding Edge post, I learned that typing mix phoenix.new
will first use the version installed into ~/.mix/archives, and then the code in the current directory.
Let’s make sure we don’t have any other versions of the Phoenix Installer (the phoenix.new mix task) around:
To be absolutely sure, modify the version number in installer/mix.exs
to something other than the last released version. I changed mine to “1.0.1-dev” indicating that this is a development or pre-release 1.0.1 version. You can also just append a dash and your username. Anything is better than potentially re-building a version number that has already been officially released. That way lies madness.
Now check the version that is in use:
If the version it reports matches what you just changed in installer/mix.exs
, then you can be sure that you’re using the code in the current directory, vs. code in an archive somewhere else.
Create A Project
We’re finally ready to try it out! Remember to use the --dev
switch as well as the --database
switch, and to specify mongodb
.
Double check that you are still in the installer
directory.
Take a look at mix.exs
in your generated project and notice that the phoenix dependency is using a relative path to point at the source code two levels up from the project location. If you move the generated project elsewhere, you’ll need to modify this.
Make sure MongoDB is running locally or the next steps won’t work.
Generate The Model
Let’s go ahead and create the database and a simple model.
Note that there is no need to run mix ecto.migrate
because there is no table structure to maintain. (And no migration file was created in priv/repo/migrations
.) Running it won’t hurt, however, it will just tell you “Already up”. I commented on the PR mentioning this and there is some discussion about suppressing the message.
Start the Server
Now for the moment of truth. Start the server:
And then visit http://localhost:4000/users. Try out the add/edit/delete functions.
Now for the good part, and why I have been waiting for this before moving on with my side project: You can add and remove fields at will, without ‘migrating’ the database structure.
Try adding an “age” field to the model and to the form – it just works. Add a column to the index.html.eex template to see the new data displayed.
MongoDB Console
To see what’s been added to the database, fire up the Mongo console
Notice that one record is missing the “age” attribute because the record was created prior to the new field being added to the form. And that this causes no problem at all!
This is what I love about MongoDB for development – I don’t have to worry about designing the data store in advance. I can change it at will until the “right” structure emerges.
Summary
We’ve seen how to try out another contributor’s as-yet-unmerged changes and gotten a sneak peek at generating a Phoenix project with support for MongoDB.
My branch with the latest (as of 8/30) Phoenix code plus Michał’s changes is here: https://github.com/wsmoak/phoenix/tree/mongodb_installer. A tag with the branch contents as of this post is here: https://github.com/wsmoak/phoenix/tree/20150830
The code for this example is available at https://github.com/wsmoak/my_app_mongodb/tree/20150831 and is MIT licensed. (Note that the phoenix dependency uses the previously mentioned branch, which may have been updated since this was written.)
Copyright 2015 Wendy Smoak - This post first appeared on http://wsmoak.github.io and is CC BY-NC licensed.
References: