DEV Community

Cover image for Thank you Rails for the carry
Surapat Mekvanich
Surapat Mekvanich

Posted on

Thank you Rails for the carry

Hello all,

I've picked up Ruby recently in my bootcamp program. We initially started with the vanilla Ruby to build our backend. Much like vanilla JavaScript that I had learned previously, everything had to be code manually.

Anyways, we had to utilize Sinatra (Domain Specific Language) to make use of ActiveRecord in Ruby to establish Object Relational Mapping (ORM) to use in our backend (API). It was such a tedious bits of work. It was a lot of typing the same thing over and over.

And then we were introduced Rails.

From having to type these migration files out manually.

class CreateProducts < ActiveRecord::Migration[6.1]
  def change
    create_table :Products do |t|
      t.integer :farm_id
      t.string :name
      t.string :category
      t.string :description
      t.string :picture_link
      t.integer :price
      t.integer :stock
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

Into, typing these inside the terminal

rails g migration product name category description picture_link price:integer stock:integer farm:belongs_to --no-test-framework
Enter fullscreen mode Exit fullscreen mode

As an efficient (lazy) wannabe web app programmer that I am- this changes everything.

'Rails g' calls upon the generator method (you'll come to love this) pre-built into the rails to generation a migration file. The convention is as followed 'rails g migration' + 'name of the table' + 'columns (in which, if not specified data type, will all be considered by strings): data_type' and the '--no-test-framework' is to not interrupt any rspec (tests) files that were created (if you were in a class setting which provided you tests to guide you).
**Also the 'belongs_to' is used to establish many-to-many relationship with another table.

You can already see how much heavy lifting (typing) these generator methods will save you from. Oh yeah, did I mention there are more methods than just for creating migration?

Image description

"YES, YOU CAN CREATE A WHOLE NEW API WITH COUPLE KEYSTROKES.
THIS THING IS A MVC FRAMEWORK ON RUBY. BASICALLY RUBY ON STEROIDS. SO EASY TO USE IT'S SCARY." -me

First of all, I would make sure that you have ruby and rails installed properly. I would follow this tutorial (https://www.youtube.com/watch?v=fmyvWz5TUWg&t=1792s) since I won't pretend that I know how to fix your problem if something goes wrong with initial set up.

Once everything is all set up. I would go into your terminal and direct to where you want this file/project to live in. (Yes, we are going to walkthrough how to make your own customizable API)

Start with,

rails new my_api --api
Enter fullscreen mode Exit fullscreen mode

Please Please Please don't use 'my_api' as your API name. Pick some other interesting name. Also don't forget '--api' at the end so rails doesn't generate all the other stuff you don't need. Even if you do it's nbd. Start over or play with the new stuff that comes with it.

Depending on how fast your computer is this step will take a (short) while. It also lists all the required gem into gemfiles. Might as well run in your terminal 'bundle install' when it's done generating everything.

bundle install
Enter fullscreen mode Exit fullscreen mode

Then you'll want to create some sort of seed data to fill your migration table. (pro tip: use Faker gem with loops)

Here's where the magic happens. Type,

rails g resource some_table name number:integer date:date 
Enter fullscreen mode Exit fullscreen mode

WALLA

You have now generated migration file, model, controller, and routes in config/routes.rb!

Now you have basically a skeleton file that was generated by rails. But we're not done yet!

Always Always Always, make sure your migration file looks right and that there are no typos. This will snowball into a headache you do not want when you cannot access your API.

Rails is especially picky with generator command with/without pluralization at the end.

-rails g scaffold* (no pluralized name)
-rails g resource (no pluralized name)
-rails g migration (no pluralized name)
-rails g model (no pluralized name)
-rails g controller (pluralized name)

If I make a mistake here and you fail your test please let your instructor know that you tried to follow this noob guide and he was wrong.

Then go into your model and establish some validation to filter data that goes into your database. It can be as simple as

class Product < ApplicationRecord
  validates :name, :number, :date, presence: true
end
Enter fullscreen mode Exit fullscreen mode

Just to make sure there are no empty data in any of the column going into your database.

Then go into your controller to set up how your API would receive the request from frontend and package what information to send back.

class ProductsController < ApplicationController
    before_action :find_product, only: [:show, :update, :destroy]

    def index
        products = Product.all
        render json: products, status: :ok
    end

    def show
        render json: @product, status: :ok
    end

    def create
        new_product = Product.create!(new_product_params)
        render json: new_product, status: :created
    end

    def update
        @product.update!(edit_product_params)
        render json: @product, status: :accepted
    end

    def destroy
        @product.destroy
        head :no_content
    end

    def fruits
        fruits = Product.all.where(category: "fruit")
        render json: fruits, status: :ok
    end

    def vegetables
        vegetables = Product.all.where(category: "vegetable")
        render json: vegetables, status: :ok
    end

    private

    def find_product
        @product = Product.find(params[:id])
    end

    def edit_product_params
        params.permit(:stock, :price, :description)
    end

    def new_product_params
        params.permit(:name, :category, :picture_link, :description, :price, :stock)
    end

end
Enter fullscreen mode Exit fullscreen mode

This controller has full CRUD (create, read, update, destroy) and it is ready to listen to requests from frontend.

Go ahead and fire up your rails server

rails s
Enter fullscreen mode Exit fullscreen mode

Now go into one of your Chrome/Firefox (I recommend installing JSON reader on Chrome, Firefox can read JSON format by default) and type

localhost:3000/
Enter fullscreen mode Exit fullscreen mode

You should see something like this.
Image description

You can probably tell that this is not the right address..

Try in your web browser,

localhost:3000/products
Enter fullscreen mode Exit fullscreen mode

or

localhost:3000/products/1
Enter fullscreen mode Exit fullscreen mode

Right now we can't really test the other actions (create, update, or destroy) unless you have POSTMAN (cough my other posts cough).

But wait... did we ever establish the routes?

AHA, Rails is back at it again with heavy lifting. With the 'resource' generator method it also generates the default 6 methods (with --api) according to the RESTful routes.

Try in your terminal

rails routes
Enter fullscreen mode Exit fullscreen mode

These are all default routes that comes with 'rails g resource'

     Prefix Verb   URI Pattern                                                                                       Controller#Action
                                products GET    /products(.:format)                                                                               products#index
                                         POST   /products(.:format)                                                                               products#create
                                 product GET    /products/:id(.:format)                                                                           products#show
                                         PATCH  /products/:id(.:format)                                                                           products#update
                                         PUT    /products/:id(.:format)                                                                           products#update
                                         DELETE /products/:id(.:format)                                                                           products#destroy
Enter fullscreen mode Exit fullscreen mode

And if you go into your config/routes.rb

Rails.application.routes.draw do
  resources :products # this generates all the default routes
end
Enter fullscreen mode Exit fullscreen mode

This is one of the ways Rails makes it easier for you to make your custom API.

*If you do 'rails g scaffold' it also create all the controller actions for you

Thanks for reading!

Top comments (0)