Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions lib/songify.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
39 changes: 34 additions & 5 deletions lib/songify/album_repo.rb
Original file line number Diff line number Diff line change
@@ -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
Expand Down
21 changes: 18 additions & 3 deletions lib/songify/genre_repo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down
9 changes: 8 additions & 1 deletion lib/songify/song_repo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
45 changes: 43 additions & 2 deletions server.rb
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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"
Expand All @@ -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
2 changes: 1 addition & 1 deletion spec/repos/album_repo_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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' })
Expand Down
9 changes: 9 additions & 0 deletions spec/repos/song_repo_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
95 changes: 90 additions & 5 deletions views/albums/index.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,98 @@

<ul>
<% @albums.each do |album| %>
<li><%= album['title'] %></li>
<% album_data = @song_count_by_album_id.find { |h| h['album_id'] == album['id'] } %>
<li>
<a href='/albums/<%= album['id'] %>'><%= album['title'] %> - <%= album_data['tracks'] %> Track(s)</a>
<button
href='/albums/<%= album['id'] %>/delete'
class="delete"
data-confirm="Are you sure to delete this album?">
Delete
</button>
</li>
<% end %>
</ul>

<form action="/albums" method="post">
<form class="album" action="/albums" method="post">
<h3>New Album</h3>
<label>Album Title:</label>
<input name="title" type="text" />
<button>Create Album</button>
<p>
<label>Album Title:</label>
<input name="title" type="text" />
<div id="genreSelectors">
<div id="genreSelector">
<select name="genre_ids[]" class = "main genre">
<option value="genre0" selected disabled>Select Genre</option>
<% @genres.each_index do |i| %>
<option value="<%= @genres[i]['id']%>"><%= @genres[i]['name']%></option>
<% end %>
</select>
<a href="#" class="add-genre">add genre</a><br />
</div>
</div>
</p>
<p>
<label>Songs:</label><br>
<div id="songlist">
<input class = "song" name="songs[]" type="text" value="Track 1"/>
<a href="#" class="add-song">add song</a><br />
</div>
</p>
<button type="submit" value="Create Album">Create Album</button>

</form>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">

// Add a New Song Textbox
$('a.add-song').on('click', function(e) {
e.preventDefault()

// Create Next Track Number
var trackText = "Track " + ($('input.song').length + 1)

// Create New Song Textbox
var $newSong = $('<input>').addClass('song').attr('name', 'songs[]').attr('type', 'text').attr('value', trackText)

// Append Textbox
$('#songlist').append($newSong).append('<br />')
})

// Add a New Genre Selector
$('a.add-genre').on('click', function(e) {
e.preventDefault()
console.log("Add")
// Create New Song Textbox

var $cloneSelector = $('select.main').clone().removeClass('main')

// Include 'Remove-Genre' Anchor
var $removeAnchor = $('<a>').attr('href', "#").addClass('remove-genre').text("remove genre")

var $genreSelector = $('<div>').attr('id', "genreSelector").append($cloneSelector).append($removeAnchor).append('<br />')

// Add Genre Selector
$('#genreSelectors').append($genreSelector)

})

// Remove Genre Selector
$(document).on('click', 'a.remove-genre', function(e) {
e.preventDefault()
console.log("Remove")
$(e.target).parent().remove()
})

// Delete Album Listeners
$(document).on('click', 'button.delete', function(event) {
event.preventDefault();

var choice = confirm(this.getAttribute('data-confirm'));

if (choice) {
window.location.href = this.getAttribute('href');
}
});

</script>
8 changes: 8 additions & 0 deletions views/albums/showpage.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<a href="/">&lt;- Back to Everything</a>
<h1>All Songs for Album</h1>

<ul>
<% @songs.each_index do |i| %>
<li><%= i+1 %>. <%= @songs[i]['title'] %></li>
<% end %>
</ul>
Loading