Hello everyone !

This week, I have been studying about one of most favorite design pattern, MVC, with Ruby Sinatra obviously. Actually, Ruby Sinatra doesn’t require to follow Model-View-Controller (MVC) design pattern for application what we will build, but building a MVC application with Sinatra can help learn how to pieces – models, view and controllers – work together. It was exciting and I want to share what I learned.

First things first, imagine we on the restaurant. So, the chef is the model of the application, the waiter is the controller and the view is the customer. The customer cannot directly converse with the chef, just like the views of the application cannot directly talk to the models. This is where controllers come in. The controller takes the information from the user and passes it to the models, the models deal with the database of the application and then send the information back to the controller and then renders to the erb file for the showing to the user.

So, like what the instructors said, if we want to starting a new project, the key is to think first is what models are you going to have. Lets imagine the simple application that can showing the all of item in database to the view with MVC.

Before building the application, we want to make sure connection the database. We need install the driver of mysql because we use mysql to the database and in the ruby the name of driver is mysql2. To the installation just run on the terminal:

gem install mysql2

To make sure the connection, we need file ruby to connect to the database. Let say we name it db_connector.rb. Oh ya, we can also use environment variable to the db connection. We can configure it in the file .env and fill it with db information. That suppose if we have an application with many features and each features need access to the database.

So the connection db_connector.rb

require 'mysql2'

def create_db_client
    client = Mysql2::Client.new(
    :host => "localhost",
    :username => ENV["DB_USERNAME"],
    :password => ENV["DB_PASSWORD"],
    :database => ENV["DB_NAME"]
    )
    client
end

and the .env you can fill it like this

export DB_USERNAME=root
export DB_NAME=food_oms_db
export DB_PASSWORD=

And execute with source .env on your terminal and than we need routes. To understand routes, I have share in the previous blog. Sinatra routes allow to field HTTP request from a user browser and send back based on URL a user visited and the type of HTTP request (GET, POST, PUSH etc).

After everything is done, next we need add the Models, Views and Controller to make application work. I went with one models, two views and a controllers.

MODELS

The model is the ‘logic’ of a web application. This is where data is manipulated and/or saved.

For first method, will return all items with instance variable and second method will insert to the new item to database with query mysql in the clien.query.

The models that I have is :

require_relative '../db/db_connector'

class Item
	attr_reader :id, :name, :price

    def initialize(id, name, price)
        @id = id
        @name = name
        @price = price
    end

    def self.get_all_items
        client = create_db_client
        rawData = client.query("select * from items")
        items = Array.new
        rawData.each do |data|
            item = Item.new(data["id"], data["name"], data["price"])
            items.push(item)
        end
        items
    end

    def self.insert_item(name, price, category)
        client = create_db_client
        new_item = client.query("insert into items (name, price) values ('#{name}', #{price})")
        new_category = client.query("insert into item_categories (item_id, category_id) values ( LAST_INSERT_ID(), '#{category}')")
    end
end

VIEWS

This is the user-facing part of a web application or ‘front-end’ — this is the only part of the app that the user interacts with directly. Views generally consist of HTML, CSS, and Javascript. I created two views, one for showing all item and one for form that we add new item.

<h1>Daftar Item<h1>
<table>
        <tr>
            <th>Name</th>
            <th>Price</th> 
            <th></th>
            <th></th>
        </tr>
    <% items.each do |item|%>
        <tr>
            <td><%= item.name %> </td>
            <td>Rp.<%= item.price %></td>
        </tr>
    <% end %>  
</table>
<a href="/items/new">Add New Item</a>

and form with file .erb to create new item

<h1>Create new item </h1>
<form action="/items/create" method ="POST">
    <input type="text" placeholder="name" name="name">
    <input type="name" placeholder="price" name="price">
    <button type="submit">add Item</button>
</form>

CONTROLLERS

The controllers are the go-between for models and views. The controller relays data from the browser to the application, and from the application to the browser.

For first, will call method from model with get_all_items and return will send into views to showing, and in the second method we add the item into database from method insert_item from the models and we redirect in the views from router.

require './model/item'

class ItemController
    def items
    items = Item::get_all_items
    renderer = ERB.new(File.read("./views/index.erb"))
    renderer.result(binding)
    end

    def create_item(params)
        new_item = Item::insert_item(params["name"],params["price"])
    end
end


Hopefully this blog helpful to you when you go on to building an application with the help of sinatra.

Thank you!