diff --git a/.editorconfig b/.editorconfig index 6fd332de..5e566598 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,4 +10,4 @@ indent_size = 4 [*.{js,json,rb}] charset = utf-8 -indent_size = 2 +indent_size = 2 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 378d5e08..5d791d6b 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,4 @@ tmp *.log *.swp -db/*.db +db/*.db \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 14b18f92..c7cad8dc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,4 +34,4 @@ We need help from the community of Learners to maintain and improve the educational content. Everything from fixing typos, to correcting out-dated information, to improving exposition, to adding better examples, to fixing tests—all contributions to making the curriculum more effective are -welcome. +welcome. \ No newline at end of file diff --git a/Gemfile b/Gemfile index c004f4ca..558abf44 100644 --- a/Gemfile +++ b/Gemfile @@ -5,3 +5,4 @@ gem "sinatra-activerecord" gem "sqlite3" gem "pry" gem "require_all" +gem 'faker', :git => 'https://github.com/faker-ruby/faker.git', :branch => 'master' #require faker \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 9589226d..7bdf2ffb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,56 +1,79 @@ +GIT + remote: https://github.com/faker-ruby/faker.git + revision: ec06d217644cf3d66bd0e658c9b168af8f0c38c7 + branch: master + specs: + faker (2.15.1) + i18n (>= 1.6, < 2) + GEM remote: https://rubygems.org/ specs: - activemodel (6.0.3.1) - activesupport (= 6.0.3.1) - activerecord (6.0.3.1) - activemodel (= 6.0.3.1) - activesupport (= 6.0.3.1) - activesupport (6.0.3.1) + activemodel (6.0.3.4) + activesupport (= 6.0.3.4) + activerecord (6.0.3.4) + activemodel (= 6.0.3.4) + activesupport (= 6.0.3.4) + activesupport (6.0.3.4) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) zeitwerk (~> 2.2, >= 2.2.2) - coderay (1.1.1) - concurrent-ruby (1.1.6) - i18n (1.8.2) + coderay (1.1.3) + concurrent-ruby (1.1.7) + i18n (1.8.5) concurrent-ruby (~> 1.0) - method_source (0.8.2) - minitest (5.14.1) - mustermann (1.0.3) - pry (0.10.4) - coderay (~> 1.1.0) - method_source (~> 0.8.1) - slop (~> 3.4) + method_source (1.0.0) + minitest (5.14.2) + mustermann (1.1.1) + ruby2_keywords (~> 0.0.1) + pastel (0.8.0) + tty-color (~> 0.5) + pry (0.13.1) + coderay (~> 1.1) + method_source (~> 1.0) rack (2.2.3) - rack-protection (2.0.7) + rack-protection (2.1.0) rack - require_all (1.3.3) - sinatra (2.0.7) + require_all (3.0.0) + ruby2_keywords (0.0.2) + sinatra (2.1.0) mustermann (~> 1.0) - rack (~> 2.0) - rack-protection (= 2.0.7) + rack (~> 2.2) + rack-protection (= 2.1.0) tilt (~> 2.0) - sinatra-activerecord (2.0.12) - activerecord (>= 3.2) + sinatra-activerecord (2.0.21) + activerecord (>= 4.1) sinatra (>= 1.0) - slop (3.6.0) - sqlite3 (1.3.13) + sqlite3 (1.4.2) thread_safe (0.3.6) tilt (2.0.10) - tzinfo (1.2.7) + tty-color (0.6.0) + tty-cursor (0.7.1) + tty-prompt (0.22.0) + pastel (~> 0.8) + tty-reader (~> 0.8) + tty-reader (0.8.0) + tty-cursor (~> 0.7) + tty-screen (~> 0.8) + wisper (~> 2.0) + tty-screen (0.8.1) + tzinfo (1.2.8) thread_safe (~> 0.1) - zeitwerk (2.3.0) + wisper (2.0.1) + zeitwerk (2.4.2) PLATFORMS ruby DEPENDENCIES + faker! pry require_all sinatra-activerecord sqlite3 + tty-prompt BUNDLED WITH - 1.14.6 + 2.1.4 diff --git a/LICENSE.md b/LICENSE.md index 6802f2b8..ad734fae 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -4,4 +4,4 @@ Copyright (c) 2015 Flatiron School, Inc The Flatiron School, Inc. owns this Educational Content. However, the Flatiron School supports the development and availability of educational materials in the public domain. Therefore, the Flatiron School grants Users of the Flatiron Educational Content set forth in this repository certain rights to reuse, build upon and share such Educational Content subject to the terms of the Educational Content License set forth [here](http://learn.co/content-license) (http://learn.co/content-license). You must read carefully the terms and conditions contained in the Educational Content License as such terms govern access to and use of the Educational Content. -Flatiron School is willing to allow you access to and use of the Educational Content only on the condition that you accept all of the terms and conditions contained in the Educational Content License set forth [here](http://learn.co/content-license) (http://learn.co/content-license). By accessing and/or using the Educational Content, you are agreeing to all of the terms and conditions contained in the Educational Content License. If you do not agree to any or all of the terms of the Educational Content License, you are prohibited from accessing, reviewing or using in any way the Educational Content. +Flatiron School is willing to allow you access to and use of the Educational Content only on the condition that you accept all of the terms and conditions contained in the Educational Content License set forth [here](http://learn.co/content-license) (http://learn.co/content-license). By accessing and/or using the Educational Content, you are agreeing to all of the terms and conditions contained in the Educational Content License. If you do not agree to any or all of the terms of the Educational Content License, you are prohibited from accessing, reviewing or using in any way the Educational Content. \ No newline at end of file diff --git a/README.md b/README.md index b75f6185..2774262c 100644 --- a/README.md +++ b/README.md @@ -1,59 +1,42 @@ -# Module One Final Project Guidelines +# Venue and Date Tracker for Artists -Congratulations, you're at the end of module one! You've worked crazy hard to get here and have learned a ton. +# Goal: + The goal of our CLI application is to be a simple tool for Artists that allows venue and concert date tracking. This is implementing a user built database with venue locations already pre-seeded. -For your final project, we'll be building a Command Line database application. +# Symbols throughout the README: + 1. "" ==> What is displayed in the application terminal + 2. '' ==> What to type into the terminal (excluding the '') -## Project Requirements +# Prerequisites and installation guide to get started: + 1. Please have the latest version of Ruby and an environment such Visual Studio. + 2. Fork and clone a copy of this repository into your local machine. + 3. Ensure that all gems have been installed and updated correctly. This will be done for you by running 'bundle install' and 'bundle update' in the terminal. + 4. Run 'rake db:migrate' once to create a database for storage. + 5. Run 'rake:db seed' once to have Venues and corresponding locations be pre-loaded into database. -### Option One - Data Analytics Project +# As a user of our application, an artist can do a few things: + 1. Create a profile/account if they do not have one. + 2. Create a date for a venue location to perform. + 3. View all of their current dates and matching venues. + 4. Update any existing venue dates. + 5. Delete any existing concert or venue dates. -1. Access a Sqlite3 Database using ActiveRecord. -2. You should have at minimum three models including one join model. This means you must have a many-to-many relationship. -3. You should seed your database using data that you collect either from a CSV, a website by scraping, or an API. -4. Your models should have methods that answer interesting questions about the data. For example, if you've collected info about movie reviews, what is the most popular movie? What movie has the most reviews? -5. You should provide a CLI to display the return values of your interesting methods. -6. Use good OO design patterns. You should have separate classes for your models and CLI interface. +# How to use our application: + 1. To start the application, type into the terminal 'ruby bin/run.rb' - **Resource:** [Easy Access APIs](https://github.com/learn-co-curriculum/easy-access-apis) + 2. Following the prompts, simply type in your artist name and the application will look for your profile in the database. If it exists, it will pull up your profile, otherwise, your profile will be created. -### Option Two - Command Line CRUD App + 3. To access the menu, type in '0' -1. Access a Sqlite3 Database using ActiveRecord. -2. You should have a minimum of three models. -3. You should build out a CLI to give your user full CRUD ability for at least one of your resources. For example, build out a command line To-Do list. A user should be able to create a new to-do, see all todos, update a todo item, and delete a todo. Todos can be grouped into categories, so that a to-do has many categories and categories have many to-dos. -4. Use good OO design patterns. You should have separate classes for your models and CLI interface. + 4. Our program is based on number and key character typing selection. To access any of the listed options in the main menu, please type in your desired number option. -### Brainstorming and Proposing a Project Idea + 5. For example, if you choose the option "Upcoming or Past Dates" within the menu, type in '3' and more prompts will follow. -Projects need to be approved prior to launching into them, so take some time to brainstorm project options that will fulfill the requirements above. You must have a minimum of four [user stories](https://en.wikipedia.org/wiki/User_story) to help explain how a user will interact with your app. A user story should follow the general structure of `"As a , I want so that "`. For example, if we were creating an app to randomly choose nearby restaurants on Yelp, we might write: + NOTE: When selecting inner options, inputs must match what is displayed. EX: Within "Create Show", selecting a city name is case sensistive and has to be a inputted as a match to the list. -* As a user, I want to be able to enter my name to retrieve my records -* As a user, I want to enter a location and be given a random nearby restaurant suggestion -* As a user, I should be able to reject a suggestion and not see that restaurant suggestion again -* As a user, I want to be able to save to and retrieve a list of favorite restaurant suggestions + 6. Each time an option has been completed, you will have to type '0' to return to the main menu. This prompt will viewable as well. -## Instructions + 7. A brief video demonstration is linked below: -1. Fork and clone this repository. -2. Build your application. Make sure to commit early and commit often. Commit messages should be meaningful (clearly describe what you're doing in the commit) and accurate (there should be nothing in the commit that doesn't match the description in the commit message). Good rule of thumb is to commit every 3-7 mins of actual coding time. Most of your commits should have under 15 lines of code and a 2 line commit is perfectly acceptable. -3. Make sure to create a good README.md with a short description, install instructions, a contributor's guide and a link to the license for your code. -4. Make sure your project checks off each of the above requirements. -5. Prepare a video demo (narration helps!) describing how a user would interact with your working project. - * The video should: - - Have an overview of your project. (2 minutes max) -6. Prepare a presentation to follow your video. (3 minutes max) - * Your presentation should: - - Describe something you struggled to build, and show us how you ultimately implemented it in your code. - - Discuss 3 things you learned in the process of working on this project. - - Address what, if anything, you would change or add to what you have today. - - Present any code you would like to highlight. -7. *OPTIONAL, BUT RECOMMENDED*: Write a blog post about the project and process. ---- -### Common Questions: -- How do I turn off my SQL logger? -```ruby -# in config/environment.rb add this line: -ActiveRecord::Base.logger = nil -``` + *https://drive.google.com/file/d/1DrpCUfpq0eow_fq1gSAkgDGylB86Qh0J/view?usp=sharing* \ No newline at end of file diff --git a/Rakefile b/Rakefile index 508ef20e..95def954 100644 --- a/Rakefile +++ b/Rakefile @@ -5,4 +5,4 @@ desc 'starts a console' task :console do ActiveRecord::Base.logger = Logger.new(STDOUT) Pry.start -end +end \ No newline at end of file diff --git a/app/models/artist.rb b/app/models/artist.rb new file mode 100644 index 00000000..3c669a03 --- /dev/null +++ b/app/models/artist.rb @@ -0,0 +1,4 @@ +class Artist < ActiveRecord::Base + has_many :show_dates + has_many :venues, through: :show_dates +end \ No newline at end of file diff --git a/app/models/cli_command.rb b/app/models/cli_command.rb new file mode 100644 index 00000000..2b3aa869 --- /dev/null +++ b/app/models/cli_command.rb @@ -0,0 +1,130 @@ +def main_menu + puts `clear` + puts "Please type a number from the list below...\n\n" + puts "1. City List" + puts "2. Create Show" + puts "3. Upcoming or Past Dates" + puts "4. Update Existing Show" + puts "5. Delete Existing Show" + puts "6. Type 'Exit' to leave the Artist Event Scheduler" +end + +# Sign in or create account for Artist method +def create_account + print "Whats your Artist/Band name?: " + user_input = gets.chomp + new_account = Artist.find_or_create_by(name: user_input) + puts "Welcome, #{user_input}!" + new_account +end + +#HELPER METHOD for listing all available cities +def list_all_cities + index = 0 + Venue.all.each{|venue| puts "#{index += 1}. #{venue.city}"} +end + +#HELPER METHOD for listing Venue names of their respective cities +def city_venue(city) + all_venue_cities = Venue.all.select{|venue| venue.city == city} + all_venue_cities.each{|venue| puts "-#{venue.name}"} +end + +#HELPER METHOD for showing artists existing dates +def dates_of_shows_helper_method(artist) + ShowDate.all.select{|show_date| show_date.artist_id == artist.id}.map{|showdate| showdate.date} +end + +#HELPER METHOD for showing artists existing venues +def venues_of_shows_helper_method(artist) + ShowDate.all.select{|show_date| show_date.artist_id == artist.id}.map{|showdate| showdate.venue.name} +end + +#CREATE ShowDate method +def create_a_show(artist) + puts "When is your show? (MM-DD-YYY): \n\n" #Could use any format, but for designer purposes. + date = gets.chomp + puts `clear` + puts "What city is your show in?: \n\n" + list_all_cities + puts "\n" + city = gets.chomp + puts `clear` + puts "Choose a venue: \n\n" + city_venue(city) + puts "\n" + venue = gets.chomp + puts `clear` + selected_venue = Venue.find_by(name: venue) + new_show_date = ShowDate.create() + new_show_date.date = date + new_show_date.artist_id = artist.id + new_show_date.venue_id = selected_venue.id + new_show_date.save + puts "Congratulations! Your show date is #{date}, at #{venue} in #{city}!\n\n" +end + +#READ ShowDate method +def show_all_my_show(artist) + all_show_dates = dates_of_shows_helper_method(artist) + all_venue_names = venues_of_shows_helper_method(artist) + if all_show_dates == [] && all_venue_names == [] + puts "Oh no! Looks like you don't have any dates yet! Go back to the menu to create one!\n\n" + else puts "You have a show on #{all_show_dates.uniq.join(', ')} at #{all_venue_names.uniq.join(', ')}!\n\n" + end +end + +# UPDATE ShowDate method +def update_my_show(artist) + puts "Here is a list of your shows! Please type in the date you would like to change: \n\n" + puts "- #{dates_of_shows_helper_method(artist).join(", ")} at #{venues_of_shows_helper_method(artist).uniq.join(', ')}.\n\n" + date_selected = gets.chomp + puts `clear` + puts "Choose a city for the updated show: \n\n" + list_all_cities + puts "\n" + city_selected = gets.chomp + puts `clear` + puts "Choose the venue: \n\n" + city_venue(city_selected) + puts "\n" + puts "Selected Venue: \n" + venue_selected = gets.chomp + puts "\n" + puts `clear` + print "Please enter your new desired date in the format 'MM-DD-YYYY': \n\n" + new_date = gets.chomp + puts `clear` + change_date = ShowDate.all.find_by(artist_id: artist.id) + change_city = Venue.all.find_by(city: city_selected) + change_venue = Venue.all.find_by(name: venue_selected) + set_date = change_date.update(date: new_date) + set_city = change_city.update(city: city_selected) + set_venue = change_venue.update(name: venue_selected) + puts "Congratulations! Your Show for that date is now updated to #{new_date} in #{city_selected} at #{venue_selected}!\n\n" +end + +#DELETE ShowDate method +def delete_my_show(artist) + puts "Here are your shows! Please type in the date you would like to cancel and delete: \n\n" + puts "- #{dates_of_shows_helper_method(artist).uniq.join(", ")}\n\n" + puts "Selected Date: " + date_selected = gets.chomp + delete_date = ShowDate.all.find_by(artist_id: artist.id) + delete_date.destroy + puts "\n" + puts "Congratulations! Your selected show has been successfully deleted!\n\n" +end + +#Tried to implement return option: +# def return_to_menu +# input = "begin" +# while input != "return" do +# print "Type 'return' to go back to menu: " +# input = gets.chomp +# case input +# when "return" +# break +# end +# end +# end \ No newline at end of file diff --git a/app/models/show_date.rb b/app/models/show_date.rb new file mode 100644 index 00000000..11c9761a --- /dev/null +++ b/app/models/show_date.rb @@ -0,0 +1,4 @@ +class ShowDate < ActiveRecord::Base + belongs_to :artist + belongs_to :venue +end \ No newline at end of file diff --git a/app/models/venue.rb b/app/models/venue.rb new file mode 100644 index 00000000..f060f065 --- /dev/null +++ b/app/models/venue.rb @@ -0,0 +1,4 @@ +class Venue < ActiveRecord::Base + has_many :show_dates + has_many :artists, through: :show_dates +end \ No newline at end of file diff --git a/bin/run.rb b/bin/run.rb index cf08c338..89bd5946 100644 --- a/bin/run.rb +++ b/bin/run.rb @@ -1,5 +1,44 @@ require_relative '../config/environment' +#ALL VENUE INSTANCES HAVE TO BE PRELOADED +#Assume Venues already exist in the database +puts `clear` +puts "BETA Build v1.0" +puts "\n\n\nHello, and welcome to the Artist Event Scheduler!\n\n\n\n" +print "Please enter your Artist/Band Name: " +artist_name = gets.chomp +artist = Artist.find_or_create_by(name: artist_name) +puts `clear` -puts "HELLO WORLD" +input = "begin" +while input != "exit" do + print "\n\nPlease type '0' to see your list of available actions: " + input = gets.chomp + case input + when "0" + puts `clear` + main_menu + when "1" + puts `clear` + list_all_cities + when "2" + puts `clear` + create_a_show(artist) + when "3" + puts `clear` + show_all_my_show(artist) + when "4" + puts `clear` + update_my_show(artist) + when "5" + puts `clear` + delete_my_show(artist) + when "EXIT".downcase + puts `clear` + break + else + puts `clear` + puts "This is an UNKNOWN command, please try again!" + end +end \ No newline at end of file diff --git a/config/environment.rb b/config/environment.rb index 4dbe13e5..7005649c 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -1,5 +1,8 @@ require 'bundler' Bundler.require +require_all 'app/models' + ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: 'db/development.db') -require_all 'lib' + +ActiveRecord::Base.logger = nil \ No newline at end of file diff --git a/db/migrate/20201203003537_create_artist.rb b/db/migrate/20201203003537_create_artist.rb new file mode 100644 index 00000000..f7b22e55 --- /dev/null +++ b/db/migrate/20201203003537_create_artist.rb @@ -0,0 +1,7 @@ +class CreateArtist < ActiveRecord::Migration[6.0] + def change + create_table :artists do |t| + t.string :name + end + end +end \ No newline at end of file diff --git a/db/migrate/20201203003625_create_venue.rb b/db/migrate/20201203003625_create_venue.rb new file mode 100644 index 00000000..8151f1ac --- /dev/null +++ b/db/migrate/20201203003625_create_venue.rb @@ -0,0 +1,8 @@ +class CreateVenue < ActiveRecord::Migration[6.0] + def change + create_table :venues do |t| + t.string :name + t.string :city + end + end +end \ No newline at end of file diff --git a/db/migrate/20201203175042_create_show_date.rb b/db/migrate/20201203175042_create_show_date.rb new file mode 100644 index 00000000..f2f565a0 --- /dev/null +++ b/db/migrate/20201203175042_create_show_date.rb @@ -0,0 +1,9 @@ +class CreateShowDate < ActiveRecord::Migration[6.0] + def change + create_table :show_dates do |t| + t.string :date + t.integer :venue_id + t.integer :artist_id + end + end +end \ No newline at end of file diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 00000000..ba3f7cd6 --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,30 @@ +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# This file is the source Rails uses to define your schema when running `rails +# db:schema:load`. When creating a new database, `rails db:schema:load` tends to +# be faster and is potentially less error prone than running all of your +# migrations from scratch. Old migrations may fail to apply correctly if those +# migrations use external dependencies or application code. +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema.define(version: 2020_12_03_175042) do + + create_table "artists", force: :cascade do |t| + t.string "name" + end + + create_table "show_dates", force: :cascade do |t| + t.string "date" + t.integer "venue_id" + t.integer "artist_id" + end + + create_table "venues", force: :cascade do |t| + t.string "name" + t.string "city" + end + +end \ No newline at end of file diff --git a/db/seeds.rb b/db/seeds.rb new file mode 100644 index 00000000..1296c7fa --- /dev/null +++ b/db/seeds.rb @@ -0,0 +1,20 @@ +require 'faker' + +#Artist.destroy_all +#ShowDate.destroy_all +#Venue.destroy_all + +# 15.times do +# Artist.create(name:Faker::Music.band) +# end +# puts 'done' + +50.times do + Venue.create(name:Faker::GreekPhilosophers.name, city:Faker::Address.city) #state:Faker::Address.state +end +puts 'done' + +# 15.times do +# ShowDate.create(date:Faker::Date.forward(days: 23), venue_id: Venue.all.sample.id, artist_id: Artist.all.sample.id) +# end +# puts 'done' \ No newline at end of file