I refactored a controller to make the code more readable. Please have a look at it before the refactoring:
module Api
module V1
class DevicesController < ApplicationController
def create
# the params either have a :device_token or a :registration_id
if device_params['device_token'].present?
@device = Device.where(device_token: device_params['device_token']).first
else
@device = Device.where(registration_id: device_params['registration_id']).first
end
add_app_id_if_blank
# This :create method is used for new_records and
# for updating existing ones as the
# client is deliberately dumb
# and just posts to this one route
if @device == nil
@device = Device.new(device_params)
respond_to do |format|
if @device.save
format.json { render json: { "link" => "#{request.base_url}/api/v1/apps/#{@device.app.guid}/devices/#{@device.id}" }, status: :created }
else
format.json { render json: @device.errors, status: :unprocessable_entity }
end
end
else
respond_to do |format|
if @device.update_attributes(device_params)
format.json { render json: { "link" => "#{request.base_url}/api/v1/apps/#{@device.app.guid}/devices/#{@device.id}" }, status: 200 }
else
format.json { render json: @device.errors, status: :unprocessable_entity }
end
end
end
end
private
def device_params
params.require(:device).permit(:app_id, :device_token, :registration_id, :identifier_for_vendor, { tag_list: [] })
end
def add_app_id_if_blank
unless params[:device].include?(:app_id)
params[:device][:app_id] = App.where(guid: params[:app_id]).first.id
end
end
end
end
end
After my refactoring I had this result:
module Api
module V1
class DevicesController < ApplicationController
before_filter :add_app_id_if_blank, :find_or_create_device
respond_to :json
def create
if @device.update_attributes(device_params)
render json: { "link" => "#{request.base_url}/api/v1/apps/#{@device.app.guid}/devices/#{@device.id}" }, status: @status
else
render json: @device.errors, status: :unprocessable_entity
end
end
private
def device_params
params.require(:device).permit(:app_id, :device_token, :registration_id, :identifier_for_vendor, { tag_list: [] })
end
def add_app_id_if_blank
unless params[:device].include?(:app_id)
params[:device][:app_id] = App.where(guid: params[:app_id]).first.id
end
end
def find_or_create_device
@device = Device.where("device_token = ? OR registration_id = ?", device_params['device_token'], device_params['registration_id']).first
@status = 200
if @device == nil
@device = Device.new(device_params)
@status = :created
end
end
end
end
end
I would say I like everything about it but the find_or_create_device
method. Do you have an idea how to optimize this method? I don’t need the different @status
but I want to represent the correct state for the client. Even if it isn’t neccessary (since it is a dumb client). So what’s your take on this?
Thank you.