diff --git a/lib/songify.rb b/lib/songify.rb index 90548c82..67d7c368 100644 --- a/lib/songify.rb +++ b/lib/songify.rb @@ -7,38 +7,43 @@ def self.create_db_connection(dbname) def self.clear_db(db) db.exec <<-SQL - DELETE FROM albums; + DELETE FROM album_genres; DELETE FROM songs; + DELETE FROM albums; DELETE FROM genres; - /* TODO: Clear rest of the tables (books, etc.) */ SQL end def self.create_tables(db) db.exec <<-SQL - CREATE TABLE albums( + CREATE TABLE IF NOT EXISTS albums( id SERIAL PRIMARY KEY, title VARCHAR ); - CREATE TABLE songs( + CREATE TABLE IF NOT EXISTS songs( id SERIAL PRIMARY KEY, - album_id integer REFERENCES genres (id), + album_id integer REFERENCES albums (id), title VARCHAR ); - CREATE TABLE genres( + CREATE TABLE IF NOT EXISTS genres( id SERIAL PRIMARY KEY, name VARCHAR ); - /* TODO: Create song_genres table */ + CREATE TABLE IF NOT EXISTS album_genres( + id SERIAL PRIMARY KEY, + album_id integer REFERENCES albums (id), + genre_id integer REFERENCES genres (id) + ); SQL end def self.drop_tables(db) db.exec <<-SQL + DROP TABLE album_genres; DROP TABLE albums; DROP TABLE songs; DROP TABLE genres; - /* TODO: Drop song_genres table */ + SQL end end diff --git a/lib/songify/album_repo.rb b/lib/songify/album_repo.rb index 54b55451..91b0e2ab 100644 --- a/lib/songify/album_repo.rb +++ b/lib/songify/album_repo.rb @@ -1,32 +1,61 @@ +require 'pry-byebug' + module Songify class AlbumRepo def self.all(db) # Other code should not have to deal with the PG:Result. # Therefore, convert the results into a plain array. - db.exec("SELECT * FROM albums").to_a + # TODO: This has to be a JOIN table + result = db.exec("SELECT * FROM albums").to_a end def self.find(db, album_id) - db.exec("SELECT * FROM albums WHERE id=$1", [album_id]).first + # TODO: This has to be a JOIN table + sql_all_genres_for_album = %Q[ + SELECT + g.id, + g.name + FROM album_genres ag + JOIN genres g + ON g.id = ag.genre_id + WHERE ag.album_id = $1 + ] + + album = db.exec("SELECT * FROM albums WHERE id=$1", [album_id]).first + return album if album.nil? + + album['genres'] = db.exec(sql_all_genres_for_album, [album_id]).to_a + album end def self.save(db, album_data) if album_data['id'] + + # Ensure album exists + album = find(db, album_data['id']) + raise "A valid album_id is required." if album.nil? + result = db.exec("UPDATE albums SET title = $2 WHERE id = $1", [album_data['id'], album_data['title']]) self.find(db, album_data['id']) else raise "title is required." if album_data['title'].nil? || album_data['title'] == '' result = db.exec("INSERT INTO albums (title) VALUES ($1) RETURNING id", [album_data['title']]) album_data['id'] = result.entries.first['id'] + if album_data['genre_ids'] + album_data['genre_ids'].each do |genre_id| + result = db.exec("INSERT INTO album_genres (album_id, genre_id) VALUES ($1, $2) RETURNING id", [album_data['id'], genre_id]) + end + end album_data end end def self.destroy(db, album_id) - # TODO: Delete SQL statement - # ALSO DELETE SONGS - # ALSO DELETE JOIN TABLE ENTRIES BETWEEN THIS ALBUM AND ITS GENRES + # Delete SQL statement + db.exec("DELETE FROM songs WHERE album_id = $1", [album_id]) + db.exec("DELETE FROM album_genres WHERE album_id = $1", [album_id]) + db.exec("DELETE FROM albums WHERE id = $1", [album_id]) end end diff --git a/lib/songify/genre_repo.rb b/lib/songify/genre_repo.rb index 558261b5..c42fb9b7 100644 --- a/lib/songify/genre_repo.rb +++ b/lib/songify/genre_repo.rb @@ -8,7 +8,22 @@ def self.all(db) end def self.find(db, genre_id) - db.exec("SELECT * FROM genres WHERE id=$1", [genre_id]).first + + sql_all_albums_for_genre = %Q[ + SELECT + a.id, + a.title + FROM album_genres ag + JOIN albums a + ON a.id = ag.album_id + WHERE ag.genre_id = $1 + ] + + genre = db.exec("SELECT * FROM genres WHERE id=$1", [genre_id]).first + return genre if genre.nil? + + genre['albums'] = db.exec(sql_all_albums_for_genre, [genre_id]).to_a + genre end def self.save(db, genre_data) @@ -25,8 +40,8 @@ def self.save(db, genre_data) end def self.destroy(db, genre_id) - # TODO: Delete SQL statement - # ALSO DELETE JOIN TABLE ENTRIES BETWEEN THIS GENRE AND ITS ALBUMS + db.exec("DELETE FROM album_genres WHERE genre_id = $1", [genre_id]) + db.exec("DELETE FROM genres WHERE id = $1", [genre_id]) end end diff --git a/lib/songify/song_repo.rb b/lib/songify/song_repo.rb index a9fc10c0..4c23fca3 100644 --- a/lib/songify/song_repo.rb +++ b/lib/songify/song_repo.rb @@ -22,11 +22,18 @@ def self.save(db, song_data) album = AlbumRepo.find(db, song_data['album_id']) raise "A valid album_id is required." if album.nil? - result = db.exec("INSERT INTO songs (title) VALUES ($1) RETURNING id", [song_data['title']]) + result = db.exec("INSERT INTO songs (title, album_id) VALUES ($1, $2) RETURNING id", [song_data['title'], song_data['album_id']]) song_data['id'] = result.entries.first['id'] song_data end end + def self.songs_per_album(db) + db.exec("SELECT album_id, COUNT(album_id) AS tracks FROM songs GROUP BY album_id").to_a + end + + def self.songs_by_album(db, album_id) + db.exec("SELECT title FROM songs WHERE album_id = $1", [album_id]).to_a + end end end diff --git a/server.rb b/server.rb index 361bacc7..5a05ac57 100644 --- a/server.rb +++ b/server.rb @@ -1,7 +1,8 @@ require 'sinatra' require './lib/songify.rb' +require 'pry-byebug' -# set :bind, '0.0.0.0' # This is needed for Vagrant +set :bind, '0.0.0.0' # This is needed for Vagrant get '/' do erb :index @@ -10,17 +11,41 @@ get '/albums' do db = Songify.create_db_connection('songify_dev') @albums = Songify::AlbumRepo.all(db) + @genres = Songify::GenreRepo.all(db) + @songs = Songify::SongRepo.all(db) + @song_count_by_album_id = Songify::SongRepo.songs_per_album(db) erb :"albums/index" end post '/albums' do db = Songify.create_db_connection('songify_dev') + + # Add Album to album db with title and genres album = Songify::AlbumRepo.save(db, { - 'title' => params[:title] + 'title' => params[:title], + 'genre_ids' => params[:genre_ids] }) + + # Add all songs to the songs db + params[:songs].each do |song| + Songify::SongRepo.save(db, { 'album_id' => album['id'], 'title' => song }) + end + redirect to '/albums' end +get '/albums/:id' do + db = Songify.create_db_connection('songify_dev') + + @songs = Songify::SongRepo.songs_by_album(db, params[:id]) + erb :"albums/showpage" +end + +get '/albums/:id/delete' do + db = Songify.create_db_connection('songify_dev') + Songify::AlbumRepo.destroy(db, params[:id]) + redirect to '/albums' +end get '/songs' do erb :"songs/index" @@ -40,3 +65,19 @@ }) redirect to '/genres' end + +get '/genres/:id' do + db = Songify.create_db_connection('songify_dev') + @genres = Songify::GenreRepo.find(db, params[:id]) + @albums = [] + @genres['albums'].each do |album| + @albums.push(Songify::AlbumRepo.find(db, album['id'])) + end + erb :"genres/showpage" +end + +get '/genres/:id/delete' do + db = Songify.create_db_connection('songify_dev') + Songify::GenreRepo.destroy(db, params[:id]) + redirect to '/genres' +end diff --git a/spec/repos/album_repo_spec.rb b/spec/repos/album_repo_spec.rb index 3f080f05..931ebde1 100644 --- a/spec/repos/album_repo_spec.rb +++ b/spec/repos/album_repo_spec.rb @@ -45,7 +45,7 @@ def album_count } end - xit "can be assigned genres" do + it "can be assigned genres" do gid_1 = Songify::GenreRepo.save(db, { 'name' => 'rock' }) gid_2 = Songify::GenreRepo.save(db, { 'name' => 'avant-garde' }) gid_3 = Songify::GenreRepo.save(db, { 'name' => 'jazz' }) diff --git a/spec/repos/song_repo_spec.rb b/spec/repos/song_repo_spec.rb index d9a823e7..5b77dfe2 100644 --- a/spec/repos/song_repo_spec.rb +++ b/spec/repos/song_repo_spec.rb @@ -31,13 +31,22 @@ def song_count song = repo.save(db, { 'album_id' => @album_id, 'title' => "The Ally" }) expect(song['id']).to_not be_nil + expect(song['album_id']).to_not be_nil expect(song['title']).to eq "The Ally" # Check for persistence expect(song_count).to eq 1 + song_count_by_album = repo.songs_per_album(db) + song_count_by_album.each do |album_id| + expect(album_id['tracks'].to_i).to eq 1 + end + song = repo.all(db).first expect(song['title']).to eq "The Ally" + expect(song['id']).to_not be_nil + expect(song['album_id']).to_not be_nil + end it "requires a title" do diff --git a/views/albums/index.erb b/views/albums/index.erb index fa67cd23..b990a06d 100644 --- a/views/albums/index.erb +++ b/views/albums/index.erb @@ -3,13 +3,98 @@ -
+

New Album

- - - +

+ + +

+
+ + add genre
+
+
+

+

+
+

+ + add song
+
+

+ +
+ + + diff --git a/views/albums/showpage.erb b/views/albums/showpage.erb new file mode 100644 index 00000000..e54ecac8 --- /dev/null +++ b/views/albums/showpage.erb @@ -0,0 +1,8 @@ +<- Back to Everything +

All Songs for Album

+ + \ No newline at end of file diff --git a/views/genres/index.erb b/views/genres/index.erb index e62f9b7d..f5311f0d 100644 --- a/views/genres/index.erb +++ b/views/genres/index.erb @@ -3,7 +3,15 @@ @@ -13,3 +21,20 @@ + + + + diff --git a/views/genres/showpage.erb b/views/genres/showpage.erb new file mode 100644 index 00000000..16625227 --- /dev/null +++ b/views/genres/showpage.erb @@ -0,0 +1,12 @@ +<- Back to Everything +

<%= @genres['name'] %> Albums

+ + \ No newline at end of file