Basic Rails API

jordy garcia
9 min readMay 18, 2021

--

Hello friends! In this article, I will explain to you more about how to create a basic API using Ruby on Rails.

Did you ever wonder when you see “User.find(params[:id])” what those params actually is? If yes, then today will be the last day you will ever wonder what that is!

But first of all, let’s start from the beginning…

We will take a simple example with the User model, so let’s start and create our User model! Let’s say we want to create a User model with a name, email and age. So we will write in our console…

$ rails g model User name email age:integer

So, first of all I wrote “g” instead of generate, that is because “g” is short for generate, cool right? After you write your model always singular and capitalized. The reason why we always have to write it singular is that rails will create a database table in the plural, so that means that we now also have a migration to create a database table called Users. I also wrote just name and email instead of name:string and email:string, that is because if you don’t write anything it automatically convert it to a string, as the default is a string when creating models. So, now that’s out of the way let’s migrate our database.

$ rails db:migrate

So, here I wrote “db” which stands for “database” and after I wrote migrate which will migrate our migration file into our database.

So, if we go to: db/schema.rb.

We can now see that our table is created! Let’s go on and create our controller the most important one for our API.

$ rails g controller Users

So, as you can see I wrote “Users” now in plural! We should always write models in singular and controllers in plural! Try to remember that, It can save you a lot of headaches trying to solve your routing issues.

So, let’s first modify our routes. Go to config/routes.rb.

Rails.application.routes.draw doroot "users#index"resources :usersend

So I wrote: root “users#index”, that is so our home page will be the app/views/users/index.html.erb of course, you should change that depending on which file your home page should be, btw whatever you write after root will refer to “controller#method” like I wrote users which is the UsersController and after the “#”, index which will be my index method.

app/controllers/users_controller.rbUsersController < ApplicationControllerdef index
end

Ok, now we understand more what root means let’s go and check out what resources actually does in rails!

Before we wrote in our routes.rb file.

resources :users

The reason we wrote “users” in the plural is because our controller is connected to our routes file which is also plural “UsersController”.

Resources basically do everything for us! It creates all the get, put/patch and post routes. So if you write in your terminal.

$ rails routes

You will see that it already created routes for seven methods, actually eight but PUT and PATCH are the same.

So, let’s see on the left we got the path and the request it will make and on the right we can see which method in which controller is connected to that path/request.

So, lets go to our controller and start with the index as that will be our root/home page.

app/controllers/users_controller.rbclass UsersController < ApplicationController  def index    @users = User.all  endend

So, here we assign User.all, which will assign all the users to @users, which is a class variable we can use in our app/views/users/index.html.erb file, of course as it will be all the users you should use some kind of loop to go through all of them like for example.

app/views/users/index.html.erb<% @users.each do |user| %><%= user.name %><% end %>

That will print all the users their name on the home page or index.html.erb page.

Let’s go and create our show method in the UsersController.

app/controller/users_controller.rbclass UsersController < ApplicationController  def index    @user = User.all  end  def show    @user = User.find(params[:id])  endend

Ok, so there we are! In this case, we finally are using the params! So when we write “User.find()”, it will look for the user by id. If we wrote “User.find(3)”, then it will look for the user with id: 3. In this case, we will need to get the id from our params as we don’t know yet which User we will need, so let’s go back to our app/views/users/index.html.erb file.

app/views/users/index.html.erb<% @users.each do |user| %><%= link_to user.name, user_path(user) %><% end %>

So, as you can see I changed “user.name” to a link_to, which basically is an anchor tag or “<a></a>”. So whenever you make a link_to tag in Rails you write: link_to, followed by the text you want to be showing in this case the user.name else you would have to write link_to “click here”, … if you want to have self-written text. After that, you need to define the path or in anchor/a tags href, as rails got helpers for that we will use those!

Only look at the “user GET /users/:id(.:format)

So in this case, if we see the word “user” next to GET users/:id, that means that will be our rails path helper. So as you can see on the index page I wrote.

<%= link_to user.name, user_path(user) %>

Like written in my routes I used “user” followed by “_path” as you always have to write “_path” after all the words on the left of the request methods(GET, PUT, PATCH, etc.). But it is saying “users/:id” and we didn’t give the id but the whole user model inside our parentheses, but rails is smart enough to look for the id as our user model looks something like this.

id: 1
name: "John Doe"
email: "John@doe.com

And in our controller we wrote User.find(params[:id]), so it will only take the id from the params, if we wrote User.find_by(name: params[:name]) it would only take the name from our model. Let’s refactor our link_to a little bit more…

link_to user.name, user

Rails is even so smart that if you just give a model instead of a path it will know you are trying to render the show page.

So don’t forget to make a app/views/users/show.html.erb page, as we just wrote in our show method “@user = User.find(params[:id])” we will get a single user so we don’t have to create a loop.

app/views/users/show.html.erb<h1> <%= @user.name %> </h1><p> <%= @user.email %> </p><i> I am <%= @user.age %> years old </i>

Cool, so now we understand more of the controller and views I will continue just using the controller.

Let’s create our next method’s which will be the new and create.

app/controllers/users_controller.rbclass UsersController < ApplicationController  def index
@users = User.all
end
def show
@user = User.find(params[:id])
end
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
redirect_to @user
else
render "new"
end
end
private

def user_params
params.require(:user).permit(:name, :email, :age)
end

Ok so now we have a lot going on! Let’s check our routes one more time, write in your terminal.

$ rails routes

and see…

So every path with the word GET will redirect us to a view, as you can see on the right side. Remember that everything on the right is written as “controller#method”.

  • users GET /users(.:format) will use the “users#index” which is our index.html.erb file.
  • new_user GET /users/new(.:format) will use the “users#new” which is our new.html.erb file.
  • edit_user GET /users/:id/edit(.:format) will use the “users#edit” which is our edit.html.erb file.
  • user GET /users/:id(.:format) will use the “users#show” which is our edit.html.erb file.

So in our “new” method, we wrote @user = User.new, you will need to create a form in your app/views/users/new.html.erb file. Which I explain in this article.

Rails Validations and Forms.

We also have a create method that doesn’t render any page as this is a POST request like written in our “rails routes”.

Like you can see on the right It will use the create method in our UsersController.

In our create method we also wrote “@user = User.new(user_params)”, that’s because we will use “@user” to see if our user is valid and saved by writing… “if @user.save”., I will explain to you later on why we wrote “user_params” in the create method.

def create
@user = User.new(user_params)
if @user.save
redirect_to @user
else
render "new"
end
end

If the user got created/saved it will redirect us to “@user” like I said before if you just write a model in our link_to or redirect_to it will bring you to the show page.

We also got an “else” statement that will render “new”, this can be written as render “new” or render :new. It will render the new.html.erb page if it didn’t save, for example, if we have some validations on the user model which checks the presence of name, you can read how to do that in this article.

Rails Validations and Forms

So now that we understand more about the “new” and “create” methods, let’s talk about the “user_params” method. I wrote private at the bottom which will make everything written underneath private, become a private method that will only be accessible in the UsersController class, which is more secure.

def user_params
params.require(:user).permit(:name, :email, :age)
end

So it will only allow/permit to enter name, email and age.

Ok so now we need our “edit” and “update” methods.

app/controllers/users_controller.rbclass UsersController < ApplicationController  def index
@users = User.all
end
def show
@user = User.find(params[:id])
end
def new
@user = User.new(user_params)
end
def create
@user = User.new(user_params)
if @user.save
redirect_to @user
else
render "new"
end
end
def edit
@user = User.find(params[:id])
end
def update
@user = User.find(params[:id])
if @user.update(user_params)
redirect_to @user
else
render "edit"
end
end
private

def user_params
params.require(:user).permit(:name, :email, :age)
end

Like we can see in our edit method I wrote @user = User.find(params[:id]) that’s because we need to find the user we want to edit, and it will also fill in our form with the current data. Our update method is similar to our create method, the only difference is that we of course now have to find the user and instead of writing @user.save we write @user.update(user_params) and of course we would render the “edit” instead of the “new” method when the user doesn’t pass our validations to update.

That makes us come to our final method the DESTROY method, we do like to destroy things!

app/controllers/users_controller.rbclass UsersController < ApplicationController  def index
@users = User.all
end
def show
@user = User.find(params[:id])
end
def new
@user = User.new(user_params)
end
def create
@user = User.new(user_params)
if @user.save
redirect_to @user
else
render "new"
end
end
def edit
@user = User.find(params[:id])
end
def update
@user = User.find(params[:id])
if @user.update(user_params)
redirect_to @user
else
render "edit"
end
end
def destroy
@user.find(params[:id])
@user.destroy
redirect_to root_path
end
private

def user_params
params.require(:user).permit(:name, :email, :age)
end

Here we look for the user we want to destroy @user = User.find(params[:id] then we just call “@user.destroy” and of course, we need to redirect to another path if we destroy the user from the show page, otherwise it will throw us an error as the user doesn’t exist anymore after we destroy it!

The only thing we could add to make this a complete RESTful API.

  def index
@users = User.all
render json: @users
end
def show
@user = User.find(params[:id])
render json: @user
end

This would allow us to render json to our page.

This is just a basic API for beginners to understand more about the controllers.

Thanks for reading my article about controllers, I hope you enjoyed reading it as I enjoyed writing it. Next time when you create a new rails app you will be able to do it more smoothly and understand why you are taking all these steps! Have a great and hopefully sunny day.

--

--

jordy garcia

Full-Stack Web Developer. Ruby on Rails, React, Redux. JavaScript, Improving open-source projects, one commit at a time.