Back to Course

Practice · SOLID · OCP · Card 7

Adding on_hold touches how many files?

Adding a new status value should be a one-line change. In a codebase where the statuses leaked everywhere, it isn't. Spot the leak.

The code

A few places where order status is mentioned, across the codebase.

# app/models/order.rb
enum status: { pending: 0, paid: 1, shipped: 2, delivered: 3, refunded: 4 }

# app/controllers/orders_controller.rb
def index
  @orders = case params[:filter]
            when "open"  then Order.where(status: [:pending, :paid])
            when "done"  then Order.where(status: [:delivered, :refunded])
            else Order.all
            end
end

# app/services/notify_customer.rb
case order.status
when "pending"   then SendOrderConfirmation.call(order)
when "shipped"   then SendShippingNotice.call(order)
when "delivered" then SendThankYou.call(order)
end

# app/views/orders/_status_badge.html.erb
<% case order.status %>
<% when "pending"   %><span class="badge yellow">Pending</span>
<% when "paid"      %><span class="badge blue">Paid</span>
<% when "shipped"   %><span class="badge purple">Shipped</span>
<% when "delivered" %><span class="badge green">Delivered</span>
<% when "refunded"  %><span class="badge gray">Refunded</span>
<% end %>

The question

Product asks for a new status, on_hold. What's the cost across these files, and what would prevent the cost?

Take a moment. Every file that hard-codes a list of status values is a place that has to change every time the list changes. What if the list lived in one place and every consumer asked the model?