Visualize the World
2018.04.11I’d like to introduce you to my first Ruby on Rails application.
See it live / View the source code
Background
Visualize the World is a website aimed at anyone interested in world maps and in developing a nuanced global perspective. The website enables people to create customized maps with country-specific text content. Maps can be displayed using a variety of built-in map projections, only some of which may be familiar. I chose these maps in an attempt to reduce American- and European-centric biases.
With this app, you the user can perform a range of actions:
- create an account
- verify your email address
- reset your password using an email link (if you forget your password)
- delete your account
- add a map
- add a blurb about the map and give it a custom name
- select countries to be highlighted on the map
- add text about each of those countries
- change the map projection used to display the map
- make the map visible to just you or to anyone with the URL
- delete the map
- add many more maps!
What is a Rails app?
Rails is a programming language for building websites with interactive and customized user experiences. Rails has a Model-View-Controller (MVC) architecture, and encourages interactions that use the Create-Read-Update-Destroy (CRUD) model.
What is MVC / CRUD?
MVC is an architecture for designing user interfaces. An application built using MVC architecture partitions work into three sections:
- The model manages the data, specifically any logic or rules that apply to the data. For example, in this app, a model defines the concept of a user: a user has an email and a password, a valid password must be a minimum of 6 characters long, and a user can own many maps.
- The view dictates the model’s visible interface. For example, in this app, the view defines the GUI (graphical user interface) for updating maps: what does the user click on to edit a map? what does the form for updating map information look like? what does the page header and footer look like?
- The controller processes user input and modifies the models and views. For example, in this app, the controller interprets an HTTP “GET” request sent to the URL
visualize-the-world.herokuapp.com/signup
as a desire to view the form for creating a new account. Submitting an HTTP “POST” request to the same URL is interpreted as a command to create a new user; the email and password submitted with the POST request are used to create a new user in the database according to the user model’s rules. Note: the different HTTP requests are hidden from the user; the view dictates which HTTP request is issued when a button is pressed, and the user just sees a button to click on.
CRUD is a pattern for developing apps in which you categorize actions as one of four types: create, read, update, or destroy. Each of these actions is applied to a noun, such as the user model in the above MVC description, or a map model that defines the app’s notion of a map. As an example, consider how a person interacts with their account:
User action | CRUD translation |
---|---|
sign up for a new account | Create a new user |
look at a page of account settings | Read account settings |
submit a form to modify account settings | Update account settings |
click a button to delete the account | Destroy user |
HTTP verbs and URLs are translated into CRUD actions that apply to a particular model. The controller executes those actions, updates the model as necessary, generates a new view, and returns that view to the user (often in the form of a new webpage or updated content).
Implementation notes
Technical implementation (Rails functionality)
In developing the app, I drew some inspiration from Michael Hartl’s Ruby on Rails Tutorial. However, although his examples may have served as a starting point, I tweaked everything and added additional functionality to better suit my particular use case.
App hosting
The app is hosted on Heroku and is deployed using Heroku’s free dynos. Because of this, there may be some lag when visiting the site for the first time as the dynos reawaken.
- Database: Postgres
- Webserver: Puma
- SSL/TLS: Let’s Encrypt certificates are enabled in Heroku by default. Unfortunately, I found it intractably difficult to automate certificates when using free Heroku dynos and a custom domain name like
www.laurennishizaki.com
. Because of this, I settled for making the app accessible via a Heroku domain name, rather than serving it over an unsecured connection on a subdomain of my website.
Emails
The app is configured to send emails using Mailgun. Emails are sent on three different occasions: to verify a new user’s email, to reset a user’s password, and on submission of the contact form. In the last case, the email is sent to the site manager. In all other cases, the message is sent to the user email stored in the database.
Maps
All maps (including the various map projections) are SVGs, programmatically generated in client-side JavaScript using the mapping capabilities of D3.
Website aesthetics
Every part of the website appearance was designed and coded by me. The layout relies heavily on CSS grid and flexbox elements for placing items in the page.
Fonts are loaded from fonts.google.com:
- website title: Permanent Marker
- headers: BioRhyme
- body text: Open Sans
The app labels countries using the English/Anglicized name, and, if it was included in the imported library of country information, the name as it is written in the local language. These foreign-language names are typeset using Open Sans, which supports characters from a handful of other languages (namely Cyrillic, Vietnamese, and Greek). The font does not support many other languages such as Arabic, Chinese, Khmer, or Thai; for these languages, the font defaults to a sans-serif font natively supported by the user’s browser.
Remind me, where can I find this app?
The application is located at https://visualize-the-world.herokuapp.com. Go give it a try: poke around the example, create an account, and generate your own maps!