Flying off with ‘Rails’……

Cali Graham
5 min readFeb 7, 2021

For my Rails project I decided to team up and work alongside a fellow student. After some time throwing ideas around we decided to go with a wizardry/witchcraft theme, because of her love for Harry Potter. This was awesome for me, as I have never read a book or seen a movie. Jokes aside, it was a fun concept. Wizards & witches (users) can sign up and sign in either using their username and password, or log in using OmniAuth with Google. Following CRUD convention, witches can create spellbooks that contain spells, and view those of other witches. They can also edit and delete content belonging to them.

Requirements

The requirements for this project were definitely more daunting than the last (Sinatra) project. It was very clear to me that the build would be a lot larger, and more detailed. I realized very quickly that attention to organization and detail was going to be essential during this process.

Here were the overall rules I needed to follow:

Specs:

  • Using Ruby on Rails for the project
  • Include at least one has_many relationship (x has_many y; e.g. User has_many Recipes)
  • Include at least one belongs_to relationship (x belongs_to y; e.g. Post belongs_to User)
  • Include at least two has_many through relationships (x has_many y through z; e.g. Recipe has_many Items through Ingredients)
  • Include at least one many-to-many relationship (x has_many y through z, y has_many x through z; e.g. Recipe has_many Items through Ingredients, Item has_many Recipes through Ingredients)
  • The “through” part of the has_many through includes at least one user submittable attribute, that is to say, some attribute other than its foreign keys that can be submitted by the app’s user (attribute_name e.g. ingredients.quantity)
  • Include reasonable validations for simple model objects (list of model objects with validations e.g. User, Recipe, Ingredient, Item)
  • Include a class level ActiveRecord scope method (model object & class method name and URL to see the working feature e.g. User.most_recipes URL: /users/most_recipes)
  • Include signup
  • Include login
  • Include logout
  • Include third party signup/login (how e.g. Devise/OmniAuth)
  • Include nested resource show or index (URL e.g. users/2/recipes)
  • Include nested resource “new” form (URL e.g. recipes/1/ingredients/new)
  • Include form display of validation errors (form URL e.g. /recipes/new)

Confirm:

  • The application is pretty DRY
  • Limited logic in controllers
  • Views use helper methods if appropriate
  • Views use partials if appropriate

Planning

The planning stages occurred sort of all over the place. The biggest challenge I faced during this process was the arrangement of my model relationships. I found later on during the build that I was not meeting requirements for the project, and had to reevaluate a few things such as which model would represent my join table. Finally, after many diagrams were drawn and ditched, I was able to map it out to meet the requirements.

User model
Spellbook model
Spell (join) model

Set-Up

Setting up a project on rails is super easy, and actually quite fun. Simply type the following command into your terminal and wait for the magic to happen:

Now that the project has been created let’s take a look at what this builds out for us automatically:

This was my first experience using generators. There is one called ‘scaffold’ that basically does everything for your project as far as setting it up goes, but for this project that was not allowed.

I used a generator to create my models by typing the following into the command line:

Typing this command in the terminal, followed by the model name and attributes will create migrations appropriate for adding a new model.

Database Creation

Guess what I used to create my database migration? If you guessed a generator, you’re right! Thanks to the beauty of Rails, a generator will create migrations appropriate for adding a new model. This migration will already contain instructions for creating the relevant table. If you tell Rails what columns you want, then statements for adding these columns will also be created.

I got my feet wet this time with my database and my migrations. I dropped my database countless times in attempts to get my seeds right, as well as my tables. However, now I feel a lot more comfortable with this process.

MVC Structure

The actual file structure in Rails builds off of what I learned in the Sinatra module and multiplies it by about 10. There is a lot more going on in this project than I would have imagined, and it was challenging at times to stay on track with all the moving parts.

The application follows the MVC structure as Rails convention should. This is vital for separating out our concerns, which will modularize distinct functionality within an application.

Models communicate with the database, Controllers act as our liaison between the Models and the Views. Views are what the User interfaces with.

OmniAuth

This part of the application build really interests me. I think it’s super cool that with OmniAuth, the responsibility of storing user’s passwords are completely taken care of.

OmniAuth is a gem for Rails that lets you use multiple authentication providers alongside the more traditional username/password setup. For my project, I decided to use Google as my provider.

Not only does it take the responsibility of storing passwords out of the equation, but it also bypasses the sign-up process improving the overall user experience.

Options for logging in/signing up

Conclusion

Overall, I really enjoyed the process of building with Rails. There really is some magic going on in there, and I am eager to use what I have learned here to create and build a wide variety of applications.

If you’d like to check out my repo — check out my Github.

--

--