- Read Tutorial
In the last guide we built the initial feature for integrating the ability to create records and got all of our request tests passing. In following with the TDD design pattern of Red, Green, Refactor it's not time to refactor the implementation.
Refactoring Strong Parameters
Right now our notification
controller code looks like this:
# 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
This code got our tests passing, however 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. Let's create a private method called notification_params
and then pass that in when we're creating a new notification
:
# app/controllers/notifications_controller.rb class NotificationsController < ApplicationController def create @notification = Notification.create(notification_params) respond_to do |format| format.json { render action: 'show', status: :created, location: @notification} end end def show end private def notification_params params.permit(:phone, :body, :source_app) end end
Now if you run the tests you'll see that everything is still passing and now we have the ability to call the parameters from other methods, such as an update
method if we ever need to create that.
Verifying Request Success
Right now our create
action is immediately calling the ActiveRecord
create
method. This is a problem because we don't provide any fallback plan if the action fails and any good API informs the requestor if an error occurs. So 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.
Let's update this in the code:
# app/controllers/notifications_controller.rb class NotificationsController < ApplicationController def create @notification = Notification.new(notification_params) respond_to do |format| if @notification.save format.json { render action: 'show', status: :created, location: @notification} else format.json { render json: @notification.errors, status: :unprocessable_entity } end end end
In this code we're simply instantiating a new Notification
and passing it the parameters from the API call instead of trying to immediately add the record to the database. After that, inside our respond_to
block we have a conditional that checks to see if the save
method works and it responds with the appropriate JSON response.
Now if you run rspec
you'll see that we have a failure:
And this failure is the exact reason why we needed to perform this refactor! The save
call is actually failing and now that our create
action is checking for success it's letting us know that there is a problem. The issue is that our strong parameters are missing a require
statement, let's fix that:
# app/controllers/notifications_controller.rb private def notification_params params.require(:notification).permit(:phone, :body, :source_app) end
This require
call is required by Rails, however it was failing silently before we added the conditional, so that's a sign that we're headed in the right direction. Now if you run the tests you'll see that everything is passing, nice work!
In the next lesson we'll create a request
spec that ensures that clients connecting to the application will be informed when an API doesn't go through successfully.