DEV Community

Renzo Diaz
Renzo Diaz

Posted on • Updated on

How to Architect Rails Project - Part 1

When I started to build web applications with ruby on rails, I had a lot of questions that I figured out through the years of using the framework. Now in this article, I’m going to share the base structure to start building a web application.

Depending on the requirements our structure could slightly change, in this scenario, I’m going to build a simple portfolio app with a blog of articles.

Before start building our project, let’s imagine two layers one to administrate the site and the other for public access (front pages). Here is how it should look.

Modules

Admin (Dashboard):
Only admin users have access and permissions to post articles, add portfolio jobs, see reports, etc.
There are many ways to build modules, for example using ActiveAdmin gem we can crate the admin module, another way is creating engines, but we are going to set up our dashboard module from scratch.

Surface (front pages):
In this module, we’ll put all the public pages like home, about, portfolio, blog, and contact.
Once we have clear this concept, let’s kick-off creating or project…

rails new portfolio -d postgresql -T

-T = skip testing modules. We’ll focus on test and design in other article

Move under the Portfolio directory and run the following commands to create the database and migrations…

rails db:create
rails db:migrate

Until here, we have a clean project with no custom pages or modules. So, let’s start creating our project architecture.
First, under controllers create 2 folders called (admins, surface). Our tree would look like this.

app/controllers
  ├── admins
  └── surface
  └── application_controller.rb

Create these controllers under admins and surface folders base_controller.rb, blogs_controller.rb, works_controller.rb and pages_controller.rb

app/controllers
  ├── admins # Portfolio blog and work management
  │   └── base_controller.rb
  |   └── blogs_controller.rb
  |   └── works_controller.rb
  └── surface # Public pages
  │   └── pages_controller.rb
  └── application.rb

Let’s add some code to our admin controllers…

# admins/base_controller.rb
class Admins::BaseController < ApplicationController
  # Define what users can access to this module
  # Define what view layout to use 
end
#admins/works_controller.rb
# here we are extending from our Admins::BaseControler
class Admins::WorksController < Admins::BaseController
end
# admins/blogs_controllers
# Inherits from Admins::BaseController
class Admins::BlogsController < Admins::BaseController
end

Let’s add some code to our surface controller…

# surface/pages_controller.rb
class Surface::PagesController < ApplicationController
  #define our pages
  def home
  end

  def about
  end
  def work
  end

  def blog
  end

  def contact
  end
end

Next, we are going to add some routes to our app un config/routes.rb.

Rails.application.draw do
  # Define our root page
  root to: 'surface/pages#home'

  # Frontend pages

  # scope module 'surface' to get this format url `domain.com/about, domain.com/work...` 
  # and not `domain.com/surface/about...`
  scope module: 'surface' do
    get '/about', to: 'pages#about', as: 'surface_about'
    get '/work', to: 'pages#work', as: 'surface_work'
    get '/blog', to: 'pages#blog', as: 'surface_blog'
    get '/contact', to: 'pages#contact', as: 'surface_contact'
  end
end

These routes also can be isolated in files, we’ll isolate these routes in the next article.

Now, we should create our views according to our modules, let’s focus first in our Surface module, so let’s create the following folders and views.

app/views
  ├── surface/pages # Write in each file <h1>Page Name</h1> 
  │   └── home.html.erb     # I.e <h1>Home</h1>
  │   └── about.html.erb    # I.e <h1>About</h1>
  |   └── work.html.erb     # I.e <h1>Work</h1>
  |   └── blog.html.erb     # I.e <h1>Blog</h1>
  |   └── contact.html.erb  # I.e <h1>Contact</h1>
  └── partials   
  │   └── _header.html.erb
  |   └── _footer.html.erb
  └── layouts 
  |   └── application.html.erb

Now let’s edit application.html.erb under the layout folder and add the header and footer partials.

Partials are the components that will be used across the site.

Let’s add some Html links to our _header.html.erb under the partials folder...

<header>
  <h1>Logo</h1>
  <nav>
    <ul>
      <li><%= link_to 'Home', root_path %></li>
      <li><%= link_to 'About', surface_about_path %></li>
      <li><%= link_to 'Work', surface_work_path %></li>
      <li><%= link_to 'Blog', surface_blog_path %></li>
      <li><%= link_to 'Contact', surface_contact_path %></li>
    </ul>
  </nav>
</header>

Next, add the header partial to our layout applicaton.html.erb

<!DOCTYPE html>
<html>
  <head>
    <title>Portfolio</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>
  <body>
    <%= render "partials/header" %>
    <%= yield %>
  </body>
</html>

Alright! we have our surface module working perfectly 💯 if you go tho http://localhost:3000 you will be able to navigate between the pages.

demo

If you got any error through this setup, feel free to drop me a line dev.renzo.diaz@gmail.com I’ll try to answer all your doubts asap.

In the next Part 2, will cover the admin module, authentication users, dashboard layout, CRUDS, and some of the front-end stuff.

Buy me a coffee

Top comments (0)