loading...
Cover image for Whipping Up a Rails API Real Quick

Whipping Up a Rails API Real Quick

cooljasonmelton profile image Jason Melton ・4 min read

In this blog, I attempt a concise outline of the basic steps to create a Ruby on Rails RESTful API.

jump to the code on GitHub

Tutorial

Steps

  • Create New Rails Project
  • Plan Models / Relationships
  • Generate Resources
  • Create / Migrate database
  • Set Up Controllers

1. Create New Rails Project

Assuming Rails is installed, enter the following command into your terminal replacing <my-project> with the project name.

rails new <my-project> --api --database=postgresql

Flags: The --api flag will forgo some of the extra junk a full Rails app has that I do not need. The --database flag lets you specify the type of database you prefer. I chose PostgreSQL. If you do not include this flag, the default database will be SQLite.

command line

For demonstration, I’ll create an Evil Dog Catcher API.

Check out this dog catcher toy I found on Google images:

dog catcher toys

What maladjusted kid wants to play with dog catcher toys? Yikes.

2. Plan Models / Relationships

While Rails installs, now is a great time to plan the models and relationships. Having a clear idea of these ahead of time saves a lot of headaches.

I'm going with two models, Catchers and Dogs.

The relationships will be:

  1. Catchers have many Dogs.
  2. Dogs belong to Catchers.

relationship diagram

3. Generate Resources

Next, I’ll generate resources. This command quickly sets up migrations, models, controllers, and routes for each model name.

rails generate resource <model> <attribute>:<type> <attribute>:<type>

Tips: You can use g as shorthand for generate. Also, you can list another model’s name as an attribute with a type of references to automatically add a foreign key to that model.

These will be my resource commands:

rails g resource catcher name:string city:string
rails g resource dog name:string breed:string catcher:references

References gives me a foreign key for the Dog model, but I have to manually go into the Catcher model add has_many :dogs.

class Dog < ApplicationRecord
  belongs_to :catcher # set up by catcher:references
end

class Catcher < ApplicationRecord
    has_many :dogs # add this line
end

4. Create / Migrate database

With all the files generated, it’s time to get the database going. First, I double check the migration files to make sure everything looks right.

class CreateCatchers < ActiveRecord::Migration[6.0]
  def change
    create_table :catchers do |t|
      t.string :name
      t.string :city

      t.timestamps
    end
  end
end

class CreateDogs < ActiveRecord::Migration[6.0]
  def change
    create_table :dogs do |t|
      t.string :name
      t.string :breed
      t.references :catcher, null: false, foreign_key: true

      t.timestamps
    end
  end
end

Note: Notice the line under CreateDogs that starts with t.references.... Because null: false, I will not be able to create a Dog unless it has the foreign key of a Catcher. If you want to be able to create models without this, set null: true.

Since everything looks right, I will now create and migrate my database by entering these commands into the terminal:

rails db:create
rails db:migrate

I double check my progress in the following steps:

  1. In the terminal, rails c or rails console opens the console.

  2. In the console, I create a Catcher instance, Catcher.create(name: 'test'), and a Dog instance, Dog.create(name: ‘test’, catcher_id: 1). There should be no errors.

  3. I test the relationships by entering Catcher.find(1).dogs. This finds the Catcher with an id of 1 and shows me if they have any dogs. I get:

<ActiveRecord::Associations::CollectionProxy [#<Dog id: 1, name: “test”, breed: nil, catcher_id: 1, created_at: “2020–10–04 06:39:15”, updated_at: “2020–10–04 06:39:15”>]>

Since there’s no errors, it’s time for the next step.

5. Set Up Controllers

For the final step, I set up a basic index controller and test it on the Rails server.

class CatchersController < ApplicationController

    def index
        # grab an array of all catchers in db
        catchers = Catcher.all
        # render a json object of all catchers
        # include a sub array of their dogs with each catcher
        render json: catchers, include: :dogs 
    end

end

I run rails s or rails server in the terminal. I open http://localhost:3000/catchers in the browser and make sure everything is working.

browser window

Tip: For production purposes, you can open the CORS of this API to any website. Install the CORS gem by opening the Gemfile, uncommenting gem ‘rack-cors’, and run bundle install.

# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
gem 'rack-cors'

Next, access the config/application file. Find the class Application and — without altering any of the default code — insert the following:

config.middleware.insert_before 0, Rack::Cors do
    allow do
        origins '*'
        resource '*',
            :headers => :any,
            :methods => [:get, :post, :delete, :put, :patch, :options, :head],
            :max_age => 0
    end
end

Remember to change the origins before deployment or this API will be available to anyone.

Conclusion

At this point the basic API is up. The next steps will be to open up the CORS for whatever other site(s) will pull from it and set up the controllers to perform whatever actions I want the back-end to perform.

Hope this is helpful! Mostly I wanted a quick reference for setting up an API. I know Rails has a million aliases and shortcuts. If you have suggestions / corrections. Please comment or email me at jason.melton2@gmail.com.

Discussion

pic
Editor guide