Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
October 19, 2022 07:20 pm GMT

How To Create A Ruby On Rails API With Scaffold - Full 10 Step Guide In 5 Minutes

This guide is multi-use, designed for passing a code challenge but could be useful for jumping into a new codebase, or refreshing your knowledge of ruby on rails, or getting a brief overview of how an MVC (Model View Controller) framework works!

1) Commands

$ bundle install
$ npm install --prefix client

2) Generators

$ rails g scaffold lowercase_snake_formatted_name attr_default_string attr_of_type:datatype model_that_has_many_of_these:belongs_to --no-test-framework

Lowercase snake is is the only format that will turn test_model into TestModel, TestModels, has_many :test_models, etc in all the right places.

Pay attention to using belongs_to relationships in this generator as it will create the foreign key tables. We wont need to use has_many in this line ever because of the nature of where foreign keys live.

If you make a mistake . . .

$ rails destroy scaffold scaffold_to_destroy

3) Fill out model relationships

belongs_to will be created automatically
has_many will be created like so . . .

    has_many :signups, dependent: :destroy    has_many :campers, through: :signups

This is a good time to consider dependent: :destroy if applicable.

4) Fill out model validations

Here are some common ones . . .

    validates :name, presence: true    validates :age, :inclusion => 8..18    validates :email, :uniqueness: true

5) Seed

$ rails db:migrate db:seed

6) routes.rb - Fill it out correctly

If all routes are required we use

resources :model

Otherwise the following paths correspond to the following only: array symbols
GET /models => [ . . . , :index]
GET /models/:id => [ . . . , :show]
POST /models => [ . . . , :create]
PATCH /models/:id => [ . . . , :update]
DELETE /models/:id => [ . . . , :destroy]

Altogether we end up with something like . . .

resources :models, only: [:index, :show, :create]

~) As you do the following be mindful of what routes you need, or perhaps do ALL of the steps if unsure . . .

7) Clean Up Tasks

In any controllers that take params . . .

params.require(:model).permit(:attr1, :attr2)

becomes . . .

params.permit(:attr1, :attr2)

to be safe we can also add to the TOP of each of these controllers . . .

wrap_parameters format: []

We can also deal with RecordNotFound errors that will be triggered by any of the above methods a single time in application_controller.rb
We add the following . . .

  rescue_from ActiveRecord::RecordNotFound, with: :render_not_found_response  private  def render_not_found_response(exception)    render json: { error: "#{exception.model} not found" }, status: :not_found  end

In Controllers, add bang operator ! to create and update methods if they are going to be used.

def create  @model = Model.new(model_params)  if @model.save    render json: @model, status: :created, location: @model  else    render json: @model.errors, status: :unprocessable_entity  endend

becomes . . .

def create  @model = Model.create!(model_params)  render json: @model, status: :createdend

Likewise the update methods are adjusted the same way.

def update  if @model.update(model_params)    render json: @model  else    render json: @model.errors, status: :unprocessable_entity  endend

becomes as simple as . . .

def update  @model.update!(model_params)  render json: @model, status: :acceptedend

Add head :no_content to destroy routes

def destroy  @activity.destroyend

becomes . . .

def destroy  @activity.destroy  head :no_contentend

8) Add unprocessable_entity errors where needed

If we have a POST or UPDATE path in use for a model (create or update methods) we also must add to our private methods inside the controller . . .

def render_unprocessable_entity_response(invalid)  render json: { errors: invalid.record.errors.full_messages }, status: :unprocessable_entityend

since these methods take parameters (strong) and at the TOP of this controller we must add . . .

rescue_from ActiveRecord::RecordInvalid, with: :render_unprocessable_entity_response

This must be in place in each controller where POST or UPDATE are in use.

9) Special Concerns

The Instead Of case: When a user signs up for a signup instead of returning the signup we want to return what they signed up for. This is very easy we do the following for example . . .

def create  @signup = Signup.create!(signup_params)  render json: @signup, status: :createdend

becomes . . .

def create  @signup = Signup.create!(signup_params)  render json: @signup.activity, status: :createdend

@signup => @signup.activity

We can also solve this by creating a new serializer, but we dont always need to. If its a wickedly simple replace the instance with an associated instance that is formatted using the default serializer we can do it like the above.

In other words we are returning the default-formatted associated model instance of interest instead of the one being operated on.

Return All Associated Instances case: I have a user with many tickets, when I show method/route on this user I want their tickets to be returned as children. As long as model relationships and db are associated properly this is as simple as adding to the UserSerializer the following line . . .
has_many :tickets

The tickets will be formatted using the default TicketSerializer.

Its good to note here that if we have a many-to-many relationship like a doctor who has many patients through appointments we can return the patients the same way using directly a has_many :patients and the serializer should know to jump over the join table.

But Only Sometimes case: What if I dont want the tickets to come through on an index method/route when we see all the users and instead only when we see just one? Instead of modifying the main serializer, in this case UserSerializer we can make a new one . . .

$ rails g serializer user_show_tickets

Since this serializer wasnt scaffolded we need to make sure we add the appropriate main attributes at the top. They can be copied from the regular UserSerializer as long as we want them . . .

attributes :id, :name, :age, :email

Then we add the has_many here instead of in the UserSerializer. Altogether it looks something like . . .

class UserShowTicketsSerializer < ActiveModel::Serializer  attributes :id, :name, :age, :email  has_many :ticketsend

Finally, we specify that this method/route uses this serializer inside the controller where it is declared. . .

def show  render json: @user, serializer: UserShowTicketsSerializerend

We can specify a serializer to do anything on a specific route this way, however its important to note that inside a serializer we have access to the instance by calling it object if we want to access specific properties of it.

-----------------------------------------------

10) Troubleshooting

If we are using @model instance methods or a set/find private method throughout our controllers this is a good clue that we should include a line like the following at the top of the controller if we want to use that variable directly. Scaffolding takes care of this automatically, but in case its helpful . . .

before_action :set_instance, only: [:show, :update, :destroy]

Here we are saying we need to set this variable when we use the following method-routes (the ones that depend on using that variable).

If we are using the server and npm to test instead of using tests it might become critical to clear our database on re-testing in case bad data was passed into the db along the way of getting our code working . . . we can add the following to our seeds.rb . . . (above the create invocations)

puts "Clearing database"ModelOne.destroy_allModelTwo.destroy_allModelThree.destroy_all

Now, our

$ rails db:seed

works a lot like a replant.

BONUS) Comment out or remove routes in the controllers that arent being used.

Hope this is helpful, let me know if I missed anything or made errors!
-Elliot/Big Sis


Original Link: https://dev.to/elliotmangini/how-to-create-a-rails-api-with-scaffold-full-10-step-guide-in-5-minutes-29a5

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To