From 8db0b87c6429f68dac2ab2d47174987435051d70 Mon Sep 17 00:00:00 2001 From: Alex Ford Date: Tue, 9 Dec 2014 09:37:55 +0000 Subject: [PATCH 1/5] Pass all rspec tests for album_genres table. album_genres table created for many-to-many betwwen 'albums' and 'genres' tables. Include Functionality for Dynamic Multiple Songs per album. Only 1-genre per album. This comes in an array. --- lib/songify.rb | 21 ++++++++++------ lib/songify/album_repo.rb | 39 +++++++++++++++++++++++++---- lib/songify/genre_repo.rb | 4 +-- lib/songify/song_repo.rb | 9 ++++++- server.rb | 22 +++++++++++++++- spec/repos/album_repo_spec.rb | 2 +- spec/repos/song_repo_spec.rb | 9 +++++++ views/albums/index.erb | 47 +++++++++++++++++++++++++++++++---- views/albums/showpage.erb | 8 ++++++ views/genres/showpage.erb | 9 +++++++ 10 files changed, 147 insertions(+), 23 deletions(-) create mode 100644 views/albums/showpage.erb create mode 100644 views/genres/showpage.erb 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..bb280b0f 100644 --- a/lib/songify/genre_repo.rb +++ b/lib/songify/genre_repo.rb @@ -25,8 +25,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..0924a229 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(DISTINCT 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..8371630d 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,36 @@ 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 album = Songify::AlbumRepo.save(db, { 'title' => params[:title] }) + songs = params[:songs] + + # Add all songs to the songs db + 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]) + binding.pry + erb :"albums/showpage" +end get '/songs' do erb :"songs/index" 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..10e6cd58 100644 --- a/views/albums/index.erb +++ b/views/albums/index.erb @@ -3,13 +3,50 @@ -
+

New Album

- - - +

+ + + + +

+

+
+

+ 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/showpage.erb b/views/genres/showpage.erb new file mode 100644 index 00000000..af28694c --- /dev/null +++ b/views/genres/showpage.erb @@ -0,0 +1,9 @@ +<- Back to Everything +

All Albums for Genre

+ +