From 6c6a672299bf95af148acbbd5aaa84973c2cfef1 Mon Sep 17 00:00:00 2001 From: greg Date: Mon, 8 Dec 2014 15:27:37 -0600 Subject: [PATCH 1/4] adds add a song form --- lib/songify.rb | 4 ++-- server.rb | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/songify.rb b/lib/songify.rb index 90548c82..4a78ab4b 100644 --- a/lib/songify.rb +++ b/lib/songify.rb @@ -2,7 +2,7 @@ module Songify def self.create_db_connection(dbname) - PG.connect(host: 'localhost', dbname: dbname) + PG.connect(host: 'localhost', dbname: dbname, user: "ruby", password: "rubyRailsJS") end def self.clear_db(db) @@ -22,7 +22,7 @@ def self.create_tables(db) ); CREATE TABLE songs( id SERIAL PRIMARY KEY, - album_id integer REFERENCES genres (id), + album_id integer REFERENCES albums (id), title VARCHAR ); CREATE TABLE genres( diff --git a/server.rb b/server.rb index 361bacc7..44e3fe98 100644 --- a/server.rb +++ b/server.rb @@ -1,5 +1,6 @@ require 'sinatra' require './lib/songify.rb' +require 'json' # set :bind, '0.0.0.0' # This is needed for Vagrant @@ -26,6 +27,14 @@ erb :"songs/index" end +get '/songs/add' do + db = Songify.create_db_connection('songify_dev') + @albums = Songify::AlbumRepo.all(db) + @genres = JSON.generate(Songify::GenreRepo.all(db)) + + erb :"songs/add" +end + get '/genres' do db = Songify.create_db_connection('songify_dev') From 8bf645aeb08fffbc207aa3f8d293cc62983be95c Mon Sep 17 00:00:00 2001 From: greg Date: Tue, 9 Dec 2014 11:07:32 -0600 Subject: [PATCH 2/4] implements albumgenres relation. Fills album object with genres when retrieving from db --- lib/songify.rb | 13 +++++++++---- lib/songify/album_repo.rb | 25 ++++++++++++++++++++++++- lib/songify/song_repo.rb | 15 ++++++++++++--- server.rb | 11 +++++++++++ spec/repos/album_repo_spec.rb | 2 +- 5 files changed, 57 insertions(+), 9 deletions(-) diff --git a/lib/songify.rb b/lib/songify.rb index 4a78ab4b..f4fd4bef 100644 --- a/lib/songify.rb +++ b/lib/songify.rb @@ -29,15 +29,20 @@ def self.create_tables(db) id SERIAL PRIMARY KEY, name VARCHAR ); - /* TODO: Create song_genres table */ + CREATE TABLE albumgenres( + 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 albums; - DROP TABLE songs; - DROP TABLE genres; + DROP TABLE albums CASCADE; + DROP TABLE songs CASCADE; + DROP TABLE genres CASCADE; + DROP TABLE albumgenres CASCADE; /* TODO: Drop song_genres table */ SQL end diff --git a/lib/songify/album_repo.rb b/lib/songify/album_repo.rb index 54b55451..fb9b2fe5 100644 --- a/lib/songify/album_repo.rb +++ b/lib/songify/album_repo.rb @@ -5,10 +5,29 @@ 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 + #r2 = db.exec("SELECT genres.name FROM genres g JOIN albumgenres ag ON ag.genre_id = g.id WHERE a.id = $1", [album_id]) end def self.find(db, album_id) - db.exec("SELECT * FROM albums WHERE id=$1", [album_id]).first + r1 = db.exec("SELECT * FROM albums WHERE id=$1", [album_id]).first + + q = <<-SQL + SELECT + ag.album_id, + g.name + FROM genres g + JOIN albumgenres ag + ON g.id = ag.genre_id + WHERE ag.album_id=$1 + SQL + + r2 = db.exec(q, [album_id]).to_a + r1['genres'] = [] + + r2.each do |genre| + r1['genres'].push(genre['name']) + end + return r1 end def self.save(db, album_data) @@ -19,6 +38,10 @@ def self.save(db, album_data) 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'] + album_data["genre_ids"].each do |genre_id| + db.exec("INSERT INTO albumgenres (album_id, genre_id) VALUES ($1, $2)", [album_data["album_id"], genre_id]) + end + album_data end end diff --git a/lib/songify/song_repo.rb b/lib/songify/song_repo.rb index a9fc10c0..bc89aca1 100644 --- a/lib/songify/song_repo.rb +++ b/lib/songify/song_repo.rb @@ -22,11 +22,20 @@ 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.all_with_album(db) + r = db.exec <<-SQL + SELECT s.id, + s.title AS song_title, + a.title AS album_title + FROM songs s + JOIN albums a + on s.album_id = a.id + SQL + r.to_a + end end end diff --git a/server.rb b/server.rb index 44e3fe98..b7069354 100644 --- a/server.rb +++ b/server.rb @@ -24,6 +24,8 @@ get '/songs' do + db = Songify.create_db_connection('songify_dev') + @songs = Songify::SongRepo.all_with_album(db) erb :"songs/index" end @@ -34,6 +36,15 @@ erb :"songs/add" end +post '/songs/add' do + db = Songify.create_db_connection('songify_dev') + data = {} + data["title"] = params["title"] + data["album_id"] = params["album"] + Songify::SongRepo.save(db, data) + + redirect to '/songs' +end get '/genres' do 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' }) From eab724a441fdd3ff6458b2e85f7fa751f1cad575 Mon Sep 17 00:00:00 2001 From: greg Date: Tue, 9 Dec 2014 11:56:41 -0600 Subject: [PATCH 3/4] fixes all repos to satify all tests. --- lib/songify.rb | 9 ++++---- lib/songify/album_repo.rb | 42 +++++++++++++++++++++++++++-------- lib/songify/song_repo.rb | 1 + spec/repos/album_repo_spec.rb | 1 - spec/repos/song_repo_spec.rb | 1 + 5 files changed, 40 insertions(+), 14 deletions(-) diff --git a/lib/songify.rb b/lib/songify.rb index f4fd4bef..5a9a2002 100644 --- a/lib/songify.rb +++ b/lib/songify.rb @@ -7,9 +7,10 @@ def self.create_db_connection(dbname) def self.clear_db(db) db.exec <<-SQL - DELETE FROM albums; - DELETE FROM songs; - DELETE FROM genres; + DELETE FROM albumgenres CASCADE; + DELETE FROM genres CASCADE; + DELETE FROM songs CASCADE; + DELETE FROM albums CASCADE; /* TODO: Clear rest of the tables (books, etc.) */ SQL end @@ -39,10 +40,10 @@ def self.create_tables(db) def self.drop_tables(db) db.exec <<-SQL + DROP TABLE albumgenres CASCADE; DROP TABLE albums CASCADE; DROP TABLE songs CASCADE; DROP TABLE genres CASCADE; - DROP TABLE albumgenres CASCADE; /* TODO: Drop song_genres table */ SQL end diff --git a/lib/songify/album_repo.rb b/lib/songify/album_repo.rb index fb9b2fe5..99f735ac 100644 --- a/lib/songify/album_repo.rb +++ b/lib/songify/album_repo.rb @@ -4,8 +4,26 @@ 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 - #r2 = db.exec("SELECT genres.name FROM genres g JOIN albumgenres ag ON ag.genre_id = g.id WHERE a.id = $1", [album_id]) + r1 = db.exec("SELECT * FROM albums").to_a + q = <<-SQL + SELECT + ag.album_id, + g.name + FROM genres g + JOIN albumgenres ag + ON g.id = ag.genre_id + SQL + + genres = db.exec(q).to_a + genres.each do |genre| + r1.each do |album| + if(album['id'] == genre['album_id']) + album['genres']||album['genres'] = [] + album['genres'].push(genre['name']) + end + end + end + return r1 end def self.find(db, album_id) @@ -22,10 +40,12 @@ def self.find(db, album_id) SQL r2 = db.exec(q, [album_id]).to_a - r1['genres'] = [] + if(r2 != []) + r1['genres'] = [] - r2.each do |genre| - r1['genres'].push(genre['name']) + r2.each do |genre| + r1['genres'].push(genre) + end end return r1 end @@ -36,13 +56,17 @@ def self.save(db, album_data) 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']]) + + result = db.exec("INSERT INTO albums (title) VALUES ($1) RETURNING *", [album_data['title']]) album_data['id'] = result.entries.first['id'] - album_data["genre_ids"].each do |genre_id| - db.exec("INSERT INTO albumgenres (album_id, genre_id) VALUES ($1, $2)", [album_data["album_id"], genre_id]) + + if album_data["genre_ids"] + album_data["genre_ids"].each do |genre_id| + db.exec("INSERT INTO albumgenres (album_id, genre_id) VALUES ($1, $2)", [album_data["id"], genre_id]) end - album_data + end + return album_data end end diff --git a/lib/songify/song_repo.rb b/lib/songify/song_repo.rb index bc89aca1..06cb26de 100644 --- a/lib/songify/song_repo.rb +++ b/lib/songify/song_repo.rb @@ -25,6 +25,7 @@ def self.save(db, song_data) 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'] end + return song_data end def self.all_with_album(db) r = db.exec <<-SQL diff --git a/spec/repos/album_repo_spec.rb b/spec/repos/album_repo_spec.rb index 931ebde1..2c698d3c 100644 --- a/spec/repos/album_repo_spec.rb +++ b/spec/repos/album_repo_spec.rb @@ -49,7 +49,6 @@ def album_count 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' }) - album = repo.save(db, { 'title' => 'Suspicious Activity?', 'genre_ids' => [gid_1['id'], gid_2['id'], gid_3['id']] }) album = repo.find(db, album['id']) diff --git a/spec/repos/song_repo_spec.rb b/spec/repos/song_repo_spec.rb index d9a823e7..44807053 100644 --- a/spec/repos/song_repo_spec.rb +++ b/spec/repos/song_repo_spec.rb @@ -72,6 +72,7 @@ def song_count it "updates songs" do song1 = repo.save(db, { 'album_id' => @album_id, 'title' => "The Ally" }) + song1['id'] song2 = repo.save(db, { 'id' => song1['id'], 'title' => "Alicia" }) expect(song2['id']).to eq(song1['id']) expect(song2['title']).to eq "Alicia" From ff234e2620c0fe24f2aca721b944df86e165d1df Mon Sep 17 00:00:00 2001 From: greg Date: Tue, 9 Dec 2014 14:13:18 -0600 Subject: [PATCH 4/4] completes exercise 3. Allows selection of multiple genres when creating an album. --- server.rb | 4 +++- views/albums/index.erb | 45 +++++++++++++++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/server.rb b/server.rb index b7069354..4aaf768e 100644 --- a/server.rb +++ b/server.rb @@ -11,13 +11,15 @@ get '/albums' do db = Songify.create_db_connection('songify_dev') @albums = Songify::AlbumRepo.all(db) + @genres = JSON.generate(Songify::GenreRepo.all(db)) erb :"albums/index" end post '/albums' do db = Songify.create_db_connection('songify_dev') album = Songify::AlbumRepo.save(db, { - 'title' => params[:title] + 'title' => params[:title], + 'genre_ids' => params[:genres] }) redirect to '/albums' end diff --git a/views/albums/index.erb b/views/albums/index.erb index fa67cd23..12dd2b34 100644 --- a/views/albums/index.erb +++ b/views/albums/index.erb @@ -9,7 +9,46 @@

New Album

- - - + +

+
+ Remove Genre +
+ Add a genre

+ +
+ \ No newline at end of file