Integrating the Ability to Create Records
In this guide we will walk through the process of creating RSpec tests for and then implementing the ability to create records in the database.
Guide Tasks
  • Read Tutorial

In this guide we will walk through the process of creating RSpec tests for and then implementing the ability to create records in the database for our Notification resource. There are a few ways that we could test this, however for microservice based applications I typically like to use request specs since this will most closely mimic other applications calling our app. Any helpful tool of Request specs is how they can work with JSON data.

Let's start by creating a spec directory that will hold our request tests:

mkdir spec/requests

Next create a new spec file for our notifications:

touch spec/requests/notification_spec.rb

And we can implement our first test that will see if we can create a new Notification via a RESTful request:

# spec/requests/notification_spec.rb

require "rails_helper"

RSpec.describe Notification, type: :request do

  it "creates a Notification" do
    headers = {
      "ACCEPT" => "application/json"
    }

    post "/notifications",
    {
      notification: {
        phone: "5555555555",
        body: "My Message",
        source_app: "my_app_name"
      }
    }, headers

    expect(response.content_type).to eq("application/json")
    expect(response).to have_http_status(:created)
  end

end

If you're not familiar with RESTful requests this test is sending a POST request to the /notifications route and sending in a hash of values as parameters and it has two expectations:

  1. The content_type to equal application/json, which is the format our API will return
  2. The response to include the http status of created, which we're passing in as a symbol

If we run rspec spec/requests we'll get an expected error saying The action 'create' could not be found for NotificationsController. So let's add that to the NotificationController:

# app/controllers/notifications_controller.rb

class NotificationsController < ApplicationController
  def create
  end
end

Running the request spec will now say that we have a missing template, which isn't the most helpful error message to drive our development since we don't want a template for our create action, but since we're good Rails developers we know that the convention is for the create action to pass the request to the show action, so we'll ignore this for a second and instead implement the ability to create a new Notification via the request:

# app/controllers/notifications_controller.rb

class NotificationsController < ApplicationController
  def create
    Notification.create(params.permit(:phone, :body, :source_app))
  end
end

I skipped the step where we didn't implement strong parameters because I'm not a fan of spending time on steps that we already know about, eventually we'll refactor this to use a notification_params method. If you run the specs now you'll see that it's still giving the error message asking for a template, so let's give RSpec what it wants, but instead of rendering an HTML view template we'll create a JSON template:

touch app/views/notifications/show.json.erb

We'll also add in the minimal code necessary for the show action to work in the controller, both in having the create action redirect and creating the show action itself.

# app/controllers/notifications_controller.rb

class NotificationsController < ApplicationController
  def create
    @notification = Notification.create(params.permit(:phone, :body, :source_app))

    respond_to do |format|
      format.json { render action: 'show', status: :created, location: @notification}   
    end
  end

  def show
  end
end

Now all of the tests are passing, I did a little more work in this step then I usually do, so let's go through it step by step:

  1. I'm storing the newly created Notification in an instance variable.
  2. Then I setup a respond_to block to tell the application how to respond to respond to requests and setting the: render action, the status, and the location to redirect the user

Now let's refactor this code because it has a few ugly Rails antipatterns. What needs to be fixed? Let's put down a list:

  1. We're hard coding the strong parameters into the create method call, we'll need to refactor this if we're going to use strong params in any other methods.
  2. We're skipping straight to the create action, we should be first instantiating a new instance of the Notification class and then using the save method in case there is an issue saving the record to the database.

In the next lesson we're going to go through and refactor this code and correct both of these items.