RUBY

Set up a Basic MVC Framework – Part 2


This is the second part of Building an MVC Framework with Ruby. The topics we’ll cover are:

  • Part 1 – Rack Deep Dive

  • Part 2 – Set up a Basic Framework

  • Part 3 – Autoloading and Utility Methods

  • Part 4 – Better Routing

  • Part 5 – Render, Redirect & Before_Action Methods in Controllers

  • Part 6 – Extract Complexities out of View with Helpers

  • Part 7 – Reduce Rework with Generators

  • Part 8 – Set up ORM for Read/Write to Database 

  • Part 9 – Generate Database from Schema

  • Part 10 – Set up Migrations

The source code for this post is available on github.

Set up a Basic  Framework

In this post we’ll use the knowledge of rack from the previous post and build a basic framework. We’ll cover the below topics:

  • Set up our development environment
  • Create the framework gem.
  • Set up test with rspec

1. Set Up our Development Environment

Youʼll need:

• Ruby 2.0 or greater
• a text editor(sublime or any other)
• a command-line or terminal
• Git
• Bundler.
• SQLite, will be needed in part 8 to 10

If you donʼt have them, youʼll need to install them. You can install from source, from your favorite package manager, from RubyGems, or Google it and follow instructions.

2. Create the Framework gem.

For your framework to be reusable by other applications, you need to package it as a gem. Rails was packages as a gem so that other application can include and build on top of it. We will do the same for our framework. We will be calling our framework zucy.

Create a new gem called zucy

Let’s commit our changes:

2.1 Customize zucy.gemspec File

Make sure to replace “FIXME” and “TODO” in the descriptions, summary and metadata[‘allowed_push_host’] – You can’t build your gem if you have any of them in your gemspec.

 Add some development and runtime dependencies.

Each of these adds a runtime dependency (needed to run the gem at all) or a development dependency (needed to develop or test the gem)

Let’s commit our changes:

Letʼs build your gem and install it:

2.2 Create the Application Class

Open lib/zucy.rb and paste the code below.

This class is the entry point for all request. You will notice that it has a call method. Some interesting things are happening here. On line 10, a method called get_controller_and_action_for returns the controller and action method to serve the request. On line 11, the controller is instantiated and the action method is invoked via the send method of the controller object. The send method is used to called a method on an object dynamically. You can learn more about send method here. Finally a rack compatible response is returned on line 12.

How exactly is the controller and action gotten? Let’s explore get_controller_and_action_for method.

get_controller_and_action_for method implement’s a very simple routing, so weʼll just get a controller and action as simply as possible. We split the URL on “/”. The “4” just means “split no more than 4 times”. So the split assigns an empty string to “_” from before the first slash, then the controller, then the action, and then everything else un-split in one lump. For now we throw away everything after the second “/” – but itʼs still in the environment, so itʼs not really gone.

The method const_get is a piece of Ruby magic – it just means get me the constant with this name. In this case, we supply the name of the controller we want in string form. Notice that we are requiring the file that contains the constant just before calling const_get

Also, youʼll sometimes see the underscore used to mean “a value I donʼt care about”, as I do above. Itʼs actually a normal variable and you can use it however you like, but many Rubyists like to use it to mean “something Iʼm ignoring or donʼt want.”

On line 21, we check if the action returned from path is nil and if it is, use the verb as the action method to invoke. This will allow us to issue a GET request to /todolist and it will invoke the get method in TodolistController. Also if we issue a GET request to /todolist/name, it will invoke the get_name method in TodolistController.

Commit your changes

 3. Set Up Test with Rspec

Update your zucy.gemspec file with the line of code below.

This gem will give us utility methods for testing our rack app.

3.1 Set Up Example Todolist App

Our generated gem has a folder called spec. This is where all our test will reside. Since our gem will be used to build other applications, we will test it against a sample application build from the gem. We will be building a todolist example application. Create a folder called todolist in spec folder and set up it’s folder structure to look like this.

Screen Shot 2015-12-20 at 2.02.12 PM

In application.rb, paste the code below.

The second line adds app/controllers folder to the load path so that you can require sample_controller.rb file with just require "sample_controller" without specifying the folder where sample_controller lives. In line 5, we created a new class called Application which inherited from our gem’s Application class. This will be the starting point of the application. config.ru and Gemfile are added so that you can run the example application directly using

Before running the example todolist application using the above command, paste the code below in config.ru

and update your Gemfile with the code below before running bundle install.

Commit your changes

3.2 Connect Todolist App to spec_helper.rb

Update your spec_helper.rb file in spec folder to look like this.

Paste the code below into zucy_spec.rb

In line 4, we included a module from rack-test gem. This gave us access to get, post, put and delete you saw in other parts of the test. Also notice line 6 – 8. The value returned by the app method is the rack app that all request are sent to. In our case, it is the todolist application we just created. Run your test using

Notice that most of your test failed. This is because todolist app do not have TodolistController. Let’s create it. Create a file called todolist_controller.rb in the controller folder of the todolist app. Paste the code below into the file.

Run your test again. Now all test should be passing. You can test the todolist app manually in your browser by running bundle exec rackup when you are in spec/todolist folder. Before running the app, make sure you have built and installed the new version of your gem.

Commit your changes

With this, we have a fully tested micro framework for building web application. However we still have a long way to go. Keep calm and wait for the next post.

The source code for this post is available on github.

In the next post, we will look at how to autoload classes and we will create some utility methods that will be used throughout this series.

Ikem Okonkwo

About Ikem Okonkwo

Ruby Evangelist, .NET Advocate. Trainer at @andela. Passionate about education and lifelong learning. Loves good food and soccer.