Wednesday, October 12, 2016

Using Service Objects in Rails

Using Service Objects in Rails

If you have many lines of code in your Models or Controllers, you might need to extract the logics out of them and wrap them up to Service Objects

They may be:

  • A bunch of code called by many controllers.
  • Dealing with output or input.
  • A specific part of code containing domain knowledge.

Let us take the CSV file generation of the order details for example.

Create a New Directory ‘app/services’

First, let’s create a new directory ‘services’ under ‘app/’.

$cd app
$mkdir services
$cd services

Create a New File ‘app/services/document_service.rb’

Second, add a new file called ‘document_service.rb’.

Create a New Service Object called ‘DocumentService’

Third, move the code in private action query_to_csv of the orders_controller to the new service object. Now, we call this service object as DocumentService.

class DocumentService
  def initialize(order_id)
    @order_id = order_id
  end

  # Use ActiveRecord::Base.connection.exec_query to query db directly only once.
  def to_csv
    query_string = 'select a.po_number as "PO Number", c.name as "Model Name", d.name as Color,
        e.name as Size, b.price as Price, b.quantity as Quantity,
        (b.price*b.quantity) as "Total Amount"
      from orders a, orderdetails b, models c, colors d, sizes e
      where a.id = b.order_id and b.model_id=c.id and b.color_id=d.id and b.size_id=e.id and b.order_id=' + @order_id.to_s
    results = ActiveRecord::Base.connection.exec_query(query_string)
    CSV.generate(headers: true) do |csv|
      csv << results.columns
      results.rows.each do |row|
        csv << row
      end
    end
  end
end

Modify The Show Action

Four, modify the show action and delete private action query_to_csv.

def show
   :
   :
  format.csv { send_data DocumentService.new(@order.id).to_csv, filename: fn }
  end
end

That’s all! Now the order controller looks nicer and cleaner.

Further readings:

No comments:

Post a Comment