diff --git a/.rubocop.yml b/.rubocop.yml index fa6eab6..c575763 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -37,4 +37,7 @@ Layout/TrailingWhitespace: # require exactly one final newline at end of each file Layout/TrailingEmptyLines: - Enabled: true \ No newline at end of file + Enabled: true + +RSpec/MultipleExpectations: + Max: 2 \ No newline at end of file diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index a26e8b4..56476a3 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -14,7 +14,7 @@ def logged_in? def require_admin unless current_user&.role == "admin" flash[:alert] = "You do not have permission to do that." - redirect_to root_path + redirect_to dashboard_path end end diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 91905ae..863cf28 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -1,6 +1,17 @@ class DashboardController < ApplicationController + before_action :require_login + def index @recent_tracks = Track.order(created_at: :desc).limit(5) @recent_comments = Comment.order(created_at: :desc).limit(5) end + + private + + def require_login + unless logged_in? + flash[:alert] = "Please log in to access the dashboard" + redirect_to login_path + end + end end diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb new file mode 100644 index 0000000..95f2992 --- /dev/null +++ b/app/controllers/home_controller.rb @@ -0,0 +1,4 @@ +class HomeController < ApplicationController + def index + end +end diff --git a/app/controllers/samples_controller.rb b/app/controllers/samples_controller.rb new file mode 100644 index 0000000..2954d0d --- /dev/null +++ b/app/controllers/samples_controller.rb @@ -0,0 +1,24 @@ +class SamplesController < ApplicationController + before_action :require_admin + + def new + @sample = Sample.new + @tracks = Track.order(:title) + end + + def create + @sample = Sample.new(sample_params) + if @sample.save + redirect_to dashboard_path, notice: "Sample Connection created!" + else + @tracks = Track.order(:title) + render :new, status: :unprocessable_entity + end + end + + private + + def sample_params + params.require(:sample).permit(:derived_track_id, :source_track_id) + end +end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 095eeb1..c7341f0 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -5,10 +5,11 @@ def new def create user = User.find_by(username: params[:username]) + if user&.authenticate(params[:password]) session[:user_id] = user.id session[:role] = user.role - redirect_to root_path, notice: "Logged in as #{user.username}" + redirect_to dashboard_path, notice: "Logged in as #{user.username}" else flash.now[:alert] = "Invalid username or password" render :new, status: :unprocessable_entity diff --git a/app/controllers/tracks_controller.rb b/app/controllers/tracks_controller.rb index 8e6eeb7..6268b16 100644 --- a/app/controllers/tracks_controller.rb +++ b/app/controllers/tracks_controller.rb @@ -18,24 +18,28 @@ def new def create @track = Track.new(track_params) - @track.user = User.find_by(username: "Twhite") + @track.user = current_user + if @track.save redirect_to @track, notice: "Track Created!" else + @artists = Artist.alphabetical render :new, status: :unprocessable_entity end end def edit @track = Track.find(params[:id]) + @artists = Artist.alphabetical end def update @track = Track.find(params[:id]) - @track.user = User.find_by(username: "Twhite") + @track.user = current_user if @track.update(track_params) redirect_to @track, notice: "Track Updated" else + @artists = Artist.alphabetical render :edit, status: :unprocessable_entity end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb new file mode 100644 index 0000000..7f25bb4 --- /dev/null +++ b/app/controllers/users_controller.rb @@ -0,0 +1,22 @@ +class UsersController < ApplicationController + def new + @user = User.new + end + + def create + @user = User.new(user_params) + if @user.save + session[:user_id] = @user.id + redirect_to dashboard_path, notice: "Welcome, #{@user.username}!" + else + flash.now[:alert] = @user.errors.full_messages.to_sentence + render :new, status: :unprocessable_entity + end + end + + private + + def user_params + params.require(:user).permit(:username, :email, :password, :password_confirmation) + end +end diff --git a/app/helpers/home_helper.rb b/app/helpers/home_helper.rb new file mode 100644 index 0000000..23de56a --- /dev/null +++ b/app/helpers/home_helper.rb @@ -0,0 +1,2 @@ +module HomeHelper +end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb new file mode 100644 index 0000000..2310a24 --- /dev/null +++ b/app/helpers/users_helper.rb @@ -0,0 +1,2 @@ +module UsersHelper +end diff --git a/app/models/artist.rb b/app/models/artist.rb index 563c36b..cce7283 100644 --- a/app/models/artist.rb +++ b/app/models/artist.rb @@ -1,7 +1,7 @@ class Artist < ApplicationRecord has_many :tracks, dependent: :destroy - validates :name, presence: true + validates :name, presence: true, uniqueness: true # alpha scope scope :alphabetical, -> { order("LOWER(name) ASC") } diff --git a/app/models/sample.rb b/app/models/sample.rb index f02e6b7..b3d350b 100644 --- a/app/models/sample.rb +++ b/app/models/sample.rb @@ -4,6 +4,27 @@ class Sample < ApplicationRecord has_many :sample_segments, dependent: :destroy - # TODO Validate later sampler_entry_id can not be equal sampled_entry_id - # AKA a song can not sample itself or be sampled by itself + validates :derived_track_id, presence: true + validates :source_track_id, presence: true + validate :no_self_sampling + validate :no_sampling_from_future + + # a source id cannot be equal to a derived id on sample join table + def no_self_sampling + if derived_track_id == source_track_id + errors.add(:base, "A track cannot sample itself") + end + end + + # check sourceYear exist, derivedYear exist, then if derived is less than source throw error + def no_sampling_from_future + if source_track&.year && derived_track&.year && derived_track&.year < source_track&.year + errors.add(:base, "A track cannot sample from the future") + end + end + + # behavior methods + def description + "#{derived_track.title} samples #{source_track.title}" + end end diff --git a/app/models/track.rb b/app/models/track.rb index 07954bc..41c8099 100644 --- a/app/models/track.rb +++ b/app/models/track.rb @@ -27,6 +27,20 @@ class Track < ApplicationRecord source: :derived_track validates :title, presence: true - validates :year, presence: true + validates :year, numericality: { greater_than_or_equal_to: 1900, less_than_or_equal_to: Date.current.year } validates :bpm, numericality: { greater_than_or_equal_to: 0 }, allow_nil: true + + # behavior methods + + def formatted_title + "#{title} (#{year})" +end + + def sample_count + samples_used.count + end + + def sampled_by_count + sampled_by_tracks.count +end end diff --git a/app/models/user.rb b/app/models/user.rb index ac6aa84..f1bac00 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,10 +1,16 @@ class User < ApplicationRecord has_many :tracks - has_many :comments - # TODO gameplan user.delete, what happens to their entries and comments. + # future nullify user id on orphaned tracks? + has_many :comments, dependent: :destroy has_secure_password + after_initialize :set_default_role, if: :new_record? + + def set_default_role + self.role ||= "user" + end + validates :email, presence: true, uniqueness: true validates :username, presence: true, uniqueness: true diff --git a/app/views/dashboard/index.html.erb b/app/views/dashboard/index.html.erb index 7257866..352fd65 100644 --- a/app/views/dashboard/index.html.erb +++ b/app/views/dashboard/index.html.erb @@ -1,4 +1,9 @@ -
- <%= link_to "Add New Track", new_track_path %> -
\ No newline at end of file +A database of who sampled who.
+<%= flash[:notice] %>
- <% end %> - - <% if flash[:alert] %> -<%= flash[:alert] %>
- <% end %> - - <% if logged_in? %> -Logged in as <%= current_user.username %>
- <%= button_to "Logout", logout_path, method: :delete %> - <% else %> - <%= link_to "Login", login_path %> - <% end %> - - <%= yield %> - -