【问题标题】:Command line terminal restaurant app errors命令行终端餐厅应用程序错误
【发布时间】:2020-01-27 03:17:33
【问题描述】:

我正在开发一个以餐厅为主题的命令行应用程序。当应用程序启动时,会出现一个菜单,并提示用户登录注册或退出。用户登录或注册后,将出现菜单,其中包含可供用户选择的选项列表 我遇到的问题是…… 1.当用户选择选项9时,它不运行,它只是退出程序

  1. 当用户选择选项 2 时,提示找不到命令
  2. 当用户选择选项以更改其帐户信息时,然后选择选项5时,选择选项5返回主菜单时,它会退出程序

    def login_screen
    
       puts "1. Login"
       puts "2. Create account"
       puts "3. Exit"
       $selection = gets.chomp
    end
    
    puts "Hello there!!! Welcome to My Restaurant Eats. Please select from the following...."
    sleep(1)
    login_screen
    # selection = gets.chomp
    
    def show_main_menu(new_customer)
      sleep(1)
      puts "HI #{new_customer.first_last_name}, please select from the following..."
      puts "1. View all restaurants"
      puts "2. View all restaurants in your borough or city"
      puts "3. View a restaurants menus"
      puts "4. Make an order"
      puts "5. View all of your orders"
      puts "6. Add to your favorites"
      puts "7. View all of your favorites"
      puts "8. View and/or change your account information"
      puts "9. Delete account"
      puts "10. Signout"
    end
    
    sleep(1)
    
      if $selection == '1'
       sleep(1)
       puts "Enter username"
       user_name = gets.chomp
       sleep(1)
       puts "Please enter password"
       pass_word = gets.chomp
       # binding.pry
       new_customer = Customer.find_by(username: user_name)
       new_cus_pass = Customer.find_by(password: pass_word)
       # binding.pry
         if new_customer == nil
          sleep(1)
          puts "Sorry, user not found. Please try again"
          login_screen
         elsif new_customer && !new_cus_pass
           puts "Incorrect password. Please try again"
           sleep(1)
           # binding.pry
      login_screen
        else if new_customer && new_cus_pass
        sleep(1)
     show_main_menu(new_customer)
      end
    end
    
       elsif $selection == '2' #doesnt start
        sleep(1)
        puts "Enter your full name."
        fullname = gets.chomp
        sleep(1)
    
    
    puts "Enter your email address."
       email = gets.chomp
       sleep(1)
       puts "Enter your desired username."
       user_name = gets.chomp
       while Customer.exists?(username: user_name) do
    
    
       sleep(1)
        puts "This username is already taken. Please enter a different one"
        user_name = gets.chomp
        sleep(1)
        break if !Customer.exists?(username: user_name)
     end
        sleep(1)
        puts "Enter a password of your choice"
        pass_word = gets.chomp
        new_customer = Customer.create(first_last_name: fullname, email_address: email, 
        username: user_name,
        password: pass_word)
        sleep(1)
        show_main_menu(new_customer)
    
    
        elsif $selection == '3'
         sleep(1)
         exit(0)
      end
    
       # $current_user = user_name
         main_menu_selection = gets.chomp
    
        if main_menu_selection == '1'
        sleep(1)
        view = Restaurant.view_all_restaurants
        sleep(1)
        show_main_menu(new_customer)
    
        elsif main_menu_selection == '2'
          sleep(1)
          puts "Enter borough or city"
          borough_city = gets.chomp
          res_locations = Restaurant.view_res_by_location(borough_city)
          puts "The resturants in the #{borough_city} are:"
             res_locations.each do |restaurant|
               puts "#{restaurant.name}."
           end
         sleep(1)
         show_main_menu(new_customer)
    
         elsif main_menu_selection == '3' #says undefined method when turning it into a  
         method
           puts "For which resturant would you like to view its menu?"
           # view = Restaurant.view_all_restaurants
           res_name = gets.chomp
             find = Restaurant.find_by_name(res_name) #find contains the instance of the 
             restaurnt
               puts "The menu for #{res_name}, is as follows...."
               # binding.pry
               # find_a_menu = find.menus
                find_a_menu = find.menus.select do |menu|
                   menu.meal
                end
               find_a_menu.each_with_index do |menu, index|
                   puts "#{index + 1}. #{menu.menu_type}"
                   JSON.parse(menu.meal).each_with_index do |item|
                   puts "    #{item}"
                 end
                end
    
                elsif main_menu_selection == '5'
                   my_orders = Order.all.each do |all_orders|
                   all_orders.customer_id == self.customer_id
                 end
    
    
                elsif main_menu_selection == '6'
                   puts "What restaurant would you like to add to your favorites?"
                   fav_res = gets.chomp
                   fav = Restaurant.find_by(name: fav_res)
                   new_favorite = Favorite.create(restaurnt_id: fav.id, customer_id:   
                   new_customer.id)
                   puts "You have successfully added #{fav_res} to your favorites"
    
                 elsif main_menu_selection == '8'
                   sleep(1)
                   puts "1. View Account Informtion"
                   puts "2. Change Account Information"
                   puts "3. Back to main menu"
                   select = gets.chomp
               if select == '1'
                  sleep(1)
                  get_info = Customer.view_customer_info(user_name)
                  get_info.each do |information|
                  # binding.pry
                  sleep(1)
                  puts "Username: #{information.username}"
                  puts "First and Last Name: #{information.first_last_name}"
                  puts "Email Address: #{information.email_address}"
              end
                  elsif select == '2'
                    while 1==1
                      sleep(1)
                       puts "1. Change Your First and Last Name"
                       puts "2. Change Your Email Address"
                       puts "3. Change Your Username"
                       puts "4. Change Your Password"
                       puts "5. Back to main menu"
                       select_another = gets.chomp
                       if select_another  == '1'
                         sleep(1)
                         puts "What would you like to change your name to?"
                         change_name = gets.chomp
                         new_customer.update_attribute(:first_last_name, change_name)
                       elsif select_another  == '2'
                         sleep(1)
                         puts "What would you like to change your email address to?"
                         change_email = gets.chomp
                         new_customer.update_attribute(:email_address, change_email)
                      elsif select_another  == '3'
                       sleep(1)
                       puts "What would you like to change your username to?"
                       change_username = gets.chomp
                       new_customer.update_attribute(:username, change_username)
                      elsif select_another  == '4'
                       sleep(1)
                       puts "What would you like your new password to be?"
                       change_password = gets.chomp
                      new_customer.update_attribute(:password, change_password)
                    elsif select_another == '5'
                     break
                     sleep(1)
                    show_main_menu(new_customer)
                  end
                end
                elsif select == '3'
                  sleep(1)
                   show_main_menu(new_customer)
    
    
               elsif main_menu_selection == '9' #doesnt run
                # sleep(1)
                Customer.destroy_all(username: user_name)
                sleep(1)
                puts "Your account has been successfuly deleted"
                sleep(1)
                login_screen
             end
    
    
                elsif main_menu_selection == '10'
                  sleep(1)
                  puts "You have been signed out"
                  sleep(1)
                 login_screen
               end
    

【问题讨论】:

  • 这是整个应用程序代码吗?你是如何运行这个脚本的?
  • 所有sleeps 是怎么回事?找不到什么“命令”(例如,actual 错误消息是什么)?不相关,但由于(看似)任意缩进和长度,很难确定代码的头部或尾部。
  • 睡眠允许您在调出下一行代码之前等待一定的时间。你在使用 Rails @DaveNewton,如果有帮助,我可以发布我的 GitHub 呼吸,这样你就可以在你的计算机上运行它并查看
  • 没有任何实际的错误消息,我提到的只是代码中的错误,抱歉不清楚,睡眠允许您等待一段时间才能启动下一行代码@DaveNewton
  • 我知道睡眠是什么 我只是不知道它为什么会在那里。我没有看到任何与 Rails 相关的内容。

标签: ruby-on-rails ruby macos terminal


【解决方案1】:

这有点难读,但您似乎正在这里进行一些自定进度的学习。几件事:

  • 几乎每个程序员都必须学习和记住的最重要的事情之一是如果您必须滚动才能阅读整个函数或方法,那太长了! :)
  • 通过花一些时间组织代码并将其抽象为有组织的类和方法,和其他人可以更轻松地了解正在发生的事情并发现错误(以相同的逻辑排序方法正如他们所期望的那样,进步也很有帮助)
  • 您正在编写的程序将受益于使用 case 语句 (https://www.rubyguides.com/2015/10/ruby-case/),在某些其他语言中也称为“switch 语句”

您提供的代码中的缩进格式非常不一致,因此很难理解其中的很多事情没有付出大量的努力,但我猜您的问题是一旦您确认有客户通过else if new_customer && new_cus_pass,您继续拨打show_main_menu(new_customer)。如果您查看 show_main_menu 方法定义,您正在将不同的选项打印到控制台,但您从不调用 gets.chomp 来读取选择。所以这应该是你卡住的地方。

顺便说一句,查询Customer.find_by(username: user_name) AND Customer.find_by(password: pass_word) 没有多大意义,因为:

  • 用户名具有唯一性,但密码不具有唯一性;多个用户可能决定使用相同的密码
  • 因为可以多人选择同一个密码,new_cus_pass 将返回第一个拥有该密码的客户——不一定是正确的客户
  • 执行不必要的数据库调用效率非常低,因此您总是希望尽可能在第一时间获得所需的内容。您还可以在同一个查询中查询多个属性,例如Customer.find_by(username: user_name, password: pass_word);如果没有找到记录,find_by 将正常失败并返回nil

我花了很多时间将您的代码重新构建为更符合编程最佳实践的代码:

def run 
  puts "Hello there!!! Welcome to My Restaurant Eats. Please select from the following...."
  process_login
end

def process_login
  case login_screen_selection 
  when '1'
    existing_user
  when '2'
    create_account
  when '3'
    exit_application
  else 
    process_login
  end
end

def login_screen_selection
  puts "1. Login"
  puts "2. Create account"
  puts "3. Exit"
  gets.chomp
end

def existing_user 
  customer = Customer.find_by(
    username: get_username, 
    password: get_password
  )
  if customer.nil? 
    customer_not_found(username)
  else
    main_menu(customer)
  end
end

def get_username
  puts 'Enter username'
  gets.chomp
end

def get_password 
  puts "Please enter password"
  gets.chomp 
end

def customer_not_found
  puts 'Sorry, username and/or password combination not valid. Please try again'
  login_screen
end

def create_account
  # You can assign the 'get' method results to a var if you want
  customer = Customer.create(
    first_last_name: get_full_name, 
    email_address:   get_email, 
    username:        get_username,
    password:        get_password
  )
  main_menu(customer)
end

def exit_application
  exit(0)
end

def get_full_name 
  puts 'Enter your full name.'
  gets.chomp
end

def get_email 
  puts 'Enter your email address.'
  gets.chomp
end 

def get_username
  puts 'Enter your desired username.'
  username = gets.chomp 
  while Customer.exists?(username: username) do
    puts "This username is already taken. Please enter a different one"
    username = gets.chomp
    break if Customer.find_by(username: username).nil?
  end
  username
end

def get_password 
  puts "Enter a password of your choice"
  gets.chomp
end

def main_menu_selection
  puts "HI #{new_customer.first_last_name}, please select from the following..."
  puts "1. View all restaurants"
  puts "2. View all restaurants in your borough or city"
  puts "3. View a restaurants menus"
  puts "4. Make an order"
  puts "5. View all of your orders"
  puts "6. Add to your favorites"
  puts "7. View all of your favorites"
  puts "8. View and/or change your account information"
  puts "9. Delete account"
  puts "10. Signout"
  gets.chomp
end

def main_menu(customer)
  case main_menu_selection
  when '1'
    view_all_restaurants
  when '2'
    view_borough_or_city(customer)
  when '3'
    view_restaurant_menu
  when '4'
    # TODO: define this
  when '5'
    view_orders(customer)
  when '6'
    add_favorite_restaurant(customer)
  when '7'
    # TODO: define this
  when '8'
    manage_account(customer)
  when '9'
    delete_account(customer)
  when '10'
    sign_out
  end
end

def view_all_restaurants
  Restaurant.view_all_restaurants
  main_menu(customer)
end

def view_borough_or_city(customer)
  puts "Enter borough or city"
  city = gets.chomp
  puts "The resturants in the #{city} are:"
  Restaurant.view_res_by_location(city).each do |restaurant|
    puts "#{restaurant.name}."
  end
  main_menu(customer)
end

def view_restaurant_menu
  puts "For which resturant would you like to view its menu?"
  name = gets.chomp
  restaurant = Restaurant.find_by_name(name) 
  puts "The menu for #{name}, is as follows...."
  menus_with_meals = restaurant.menus.select do |menu|
    menu.meal
  end
  menus_with_meals.each_with_index do |menu, index|
    puts "#{index + 1}. #{menu.menu_type}"
    JSON.parse(menu.meal).each_with_index do |item|
    puts "    #{item}"
    end
  end
end

def view_orders(customer)
  # IMO orders should have a belongs_to association with customer
  # then you could do customer.orders
  Order.where(customer_id: customer.id)
end

def add_favorite_restaurant(customer)
  puts "What restaurant would you like to add to your favorites?"
  favorite_name = gets.chomp
  restaurant = Restaurant.find_by(name: favorite_name)
  Favorite.create(
    restaurant_id: restaurant.id, 
    customer_id:   new_customer.id
  )
  puts "You have successfully added #{favorite_name} to your favorites"
end

def manage_account(customer)
  case manage_account_selection
  when '1'
    display_customer_info(customer)
  when '2'
    update_customer_info(customer)
  when '3'
    main_menu(customer)
  end
end 

def display_customer_info(customer)
  puts "Username: #{customer.username}"
  puts "First and Last Name: #{customer.first_last_name}"
  puts "Email Address: #{customer.email_address}"
end

def manage_account_selection
  puts "1. View Account Informtion"
  puts "2. Change Account Information"
  puts "3. Back to main menu"
  gets.chomp
end

def delete_account(customer)
  # You already have a reference to the customer record, use it
  customer.destroy!
  puts 'Your account has been successfuly deleted'
  login_screen
end

def update_customer_info(customer)
  while true 
    case update_customer_info_selection
    when '1'
      update_first_last_name(customer)
    when '2'
      update_email(customer)
    when '3'
      update_username(customer)
    when '4'
      update_password(customer)
    when '5'
      main_menu(customer)
    end
  end
end

def update_customer_info_selection
  puts "1. Change Your First and Last Name"
  puts "2. Change Your Email Address"
  puts "3. Change Your Username"
  puts "4. Change Your Password"
  puts "5. Back to main menu"
  gets.chomp
end

def update_first_last_name(customer)
  puts 'What would you like to change your name to?'
  customer.update!(first_last_name: gets.chomp)
end

def update_email(customer)
  puts 'What would you like to change your email address to?'
  csutomer.update!(email_address: gets.chomp)
end

def update_username(customer)
  puts 'What would you like to change your username to?'
  customer.update!(username: gets.chomp)
end

def update_password(customer)
  puts 'What would you like your new password to be?'
  customer.update!(password: gets.chomp)
end

def sign_out
  puts "You have been signed out"
  login_screen
end

# Start the entire flow with one command!
run

请花一些时间详细查看重构后的代码,并用它来帮助塑造您将来编写代码的方式。这应该让您更清楚地了解如何编写符合编程最佳实践的结构化、可读代码。一切都被分解成小的、人类可读的方法,并且一切都按照与您在应用程序中进行的逻辑流程相同的逻辑流程进行排序。以这种方式编码使您(和其他人!)更容易理解您的代码所做的一切并跟踪错误。如果你想知道我为什么用gets.chomp 结束方法,那是因为Ruby 方法总是返回方法定义中最后一个东西的值(在这种情况下,它应该是用户在控制台中输入的值)。学习愉快:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-15
    • 2010-09-29
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-21
    • 2018-08-21
    相关资源
    最近更新 更多