'How do I reduce the nex lines of Ruby code?

    def route_action(action)
    case action
    when 1 then @meals_controller.add
    when 2 then @meals_controller.list
    when 3 then @meals_controller.edit
    when 4 then @meals_controller.delete
    when 5 then @customers_controller.add
    when 6 then @customers_controller.list
    when 7 then @customers_controller.edit
    when 8 then @customers_controller.delete
    when 0 then stop
    else
      puts "Please press 1, 2, 3, 4, 5, 6, 7, 8 or 0"
    end
  end

So I want to reduce this case when is there another way of implementing this?



Solution 1:[1]

One possibility would be to have an array of message names to send based on the action input which is used as an index, and by determining which controller to send to by dividing by 5. Inputs from 1 to 4 will yield 0, while 5 to 8 will yield 1.

def route_action
  actions = [:add, :list, :edit, :delete]

  case action
    when 1..8 
      controller = action / 5 < 1 ? @meals_controller : @customers_controller
      msg = actions[(action - 1) % 4]
      controller.send(msg)
    when 0 
      stop
    else
      puts "Please press 1, 2, 3, 4, 5, 6, 7, 8 or 0"
  end
end

Solution 2:[2]

How about:

CASES = [@meals_controller, @customers_controller].product([:add, :list, :edit, :delete])

def route_action(action)
  if action > 0
    selected = CASES[action-1] # something like [:@meals_controller, :add]
    if selected
      selected.first.send(*selected.last)
    else
      puts "action number too large"
    end
  elsif action == 0
    stop
  else # Do we have to catch this?
    puts "action number negative" # programming error?
  end
end

  

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Chris
Solution 2