Last time, I got the gem file structure set up and created an executable file that I could run in my terminal. The next step was to set up the command line interface.
See also:
- Part 1: Planning and Set Up With Bundler
- Part 3: Using Nokogiri to Scrape Data for My Objects
- Building My First Sinatra-based Ruby App: Thoughts and Wrap-up
Instead of putting the CLI code directly in the bin/find-recipe
, I wanted to create a class file that would act as the CLI controller and that could be called from the executable file through FindRecipe::CLI.new.call
.
For the CLI class and all the other program files, I think it’s better to put them under the lib/
folder. The lib folder already contained a couple items automatically generated by Bundler: a find-recipe.rb
file and another folder, find_recipe/
, which contained a version.rb
file that is used to keep track of, well, the version.
The find-recipe.rb
file contained some code already:
# lib/find_recipe.rb
require "find_recipe/version"
module FindRecipe
# Your code goes here...
end
While I could write my program code inside the FindRecipe module, for now I’m going to use the file as a way to load my environment and separate my classes into files under the lib/find_recipe/
folder (later, I think I’ll create a config folder with an environment.rb
file).
To finally get started with coding the CLI, I created a cli.rb
file inside lib/find_recipe/
. Now the basic file structure looks like this:
find_recipe
|- bin/
| |- find-recipe
| |- console
| |- setup
|- lib/
| |- find_recipe.rb
| |- find_recipe/
| | |- version.rb
| | |- cli.rb
|- spec/
|- Gemfile
|- find_recipe.gemspec
|- README.md
-
bin/ contains the executable files, notably the
find-recipe
file I created which launches my program (console and setup file were automatically generated by Bundler) - lib/ contains my program logic, like the CLI logic and later any other classes I’ll need (probably something that creates recipe objects and a scraper class that gets the data used by the recipe objects)
- spec/ is the appropriate place to put test files
The CLI class
Before writing any code for the scraper or a recipe class, first I wanted to get my user interface working. When the program launches, it would call the CLI class through the FindRecipe::CLI.new.call
method.
Since my plan is to offer two ways to get a list of recipes (trending recipes or through a search keyword), I decided to break up the CLI into several methods that would handle each task:
- The search options
- Looking at trending recipes
- Using a keyword to see recipes
- Exiting
To concentrate on just getting the CLI logic to work properly, for now, I’m using dummy data that represents recipe objects that will be scraped by the scraper class later on.
# This Class acts as the CLI Controller
class FindRecipe::CLI
def call
search_options
end
def search_options
puts ""
puts "How do you want to get started?"
puts ""
puts "1. See trending recipes"
puts "2. Search for a recipe"
puts ""
puts "Enter 1 or 2, or exit"
input = gets.strip.downcase
if input == "1"
trending_recipes
elsif input == "2"
search_recipe
elsif input == "exit"
exit
else
puts "Not sure what you mean..."
search_options
end
end
def trending_recipes
puts "1. Khaman dhokla"
puts "2. Low carb Courgette fritters"
puts "3. Bacon, Leek and Potato Soup"
puts ""
puts "Choose a recipe number or type 'back'"
input = gets.strip.downcase
if input.to_i > 0 && input.to_i <= 3
get_recipe_from_number( input.to_i )
elsif input == "back"
search_options
else
puts "Not sure what you mean..."
puts ""
trending_recipes
end
input = nil
while input != "exit"
puts "Do you want to see the list again, restart, or exit?"
puts "Enter list, restart, or exit"
input = gets.strip.downcase
if input == "list"
trending_recipes
elsif input == "restart"
search_options
end
end
exit
end
def get_recipe_from_number(number)
puts "Recipe #{number}"
end
def search_recipe
puts "What is the dish or ingredient you want to search for?"
input = gets.strip.downcase
puts "#{input} Recipes:"
exit
end
def exit
puts "See you next time!"
end
end
This seems to be working properly for now, so my next steps will be creating a recipe class so the CLI will use real recipes objects instead of dummy data and a scraper class that will get data from a live site!
P.S. You can see the git repository for this project here.
Top comments (0)