diff --git a/.ruby-version b/.ruby-version index ab6d2789..79a61441 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.4.4 \ No newline at end of file +2.4.4 diff --git a/Gemfile b/Gemfile index 3f1e6961..7d199809 100644 --- a/Gemfile +++ b/Gemfile @@ -33,9 +33,17 @@ gem 'jbuilder', '~> 2.5' # Use Capistrano for deployment # gem 'capistrano-rails', group: :development +gem 'jquery-rails' gem 'devise' gem 'simple_form' +gem 'will_paginate' +gem 'will_paginate-bootstrap' +gem 'bootstrap-sass', '~> 3.4.1' +gem 'sassc-rails', '>= 2.1.0' +gem 'autoprefixer-rails' +gem 'sprockets-rails' +gem 'annotate' # Reduces boot times through caching; required in config/boot.rb gem 'bootsnap', '>= 1.1.0', require: false @@ -45,6 +53,7 @@ group :development, :test do gem 'rspec-rails', '~> 3.7' gem 'factory_bot_rails' gem 'capybara' + gem 'launchy' gem 'pry' gem 'rails-controller-testing' end diff --git a/Gemfile.lock b/Gemfile.lock index 16c3b7bc..b890a88a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -44,11 +44,19 @@ GEM tzinfo (~> 1.1) addressable (2.5.2) public_suffix (>= 2.0.2, < 4.0) + annotate (2.7.4) + activerecord (>= 3.2, < 6.0) + rake (>= 10.4, < 13.0) arel (9.0.0) + autoprefixer-rails (9.4.10.2) + execjs bcrypt (3.1.12) bindex (0.5.0) bootsnap (1.3.0) msgpack (~> 1.0) + bootstrap-sass (3.4.1) + autoprefixer-rails (>= 5.2.1) + sassc (>= 2.0.0) builder (3.2.3) byebug (10.0.2) capybara (2.18.0) @@ -90,6 +98,12 @@ GEM jbuilder (2.7.0) activesupport (>= 4.2.0) multi_json (>= 1.2) + jquery-rails (4.3.3) + rails-dom-testing (>= 1, < 3) + railties (>= 4.2.0) + thor (>= 0.14, < 2.0) + launchy (2.4.3) + addressable (~> 2.3) listen (3.1.5) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) @@ -184,6 +198,15 @@ GEM sprockets (>= 2.8, < 4.0) sprockets-rails (>= 2.0, < 4.0) tilt (>= 1.1, < 3) + sassc (2.0.1) + ffi (~> 1.9) + rake + sassc-rails (2.1.0) + railties (>= 4.0.0) + sassc (>= 2.0) + sprockets (> 3.0) + sprockets-rails + tilt simple_form (4.0.1) actionpack (>= 5.0) activemodel (>= 5.0) @@ -220,6 +243,9 @@ GEM websocket-driver (0.7.0) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.3) + will_paginate (3.1.6) + will_paginate-bootstrap (1.0.2) + will_paginate (>= 3.0.3) xpath (3.0.0) nokogiri (~> 1.8) @@ -227,13 +253,18 @@ PLATFORMS ruby DEPENDENCIES + annotate + autoprefixer-rails bootsnap (>= 1.1.0) + bootstrap-sass (~> 3.4.1) byebug capybara coffee-rails (~> 4.2) devise factory_bot_rails jbuilder (~> 2.5) + jquery-rails + launchy listen (>= 3.0.5, < 3.2) pry puma (~> 3.11) @@ -241,17 +272,21 @@ DEPENDENCIES rails-controller-testing rspec-rails (~> 3.7) sass-rails (~> 5.0) + sassc-rails (>= 2.1.0) simple_form spring spring-watcher-listen (~> 2.0.0) + sprockets-rails sqlite3 turbolinks (~> 5) tzinfo-data uglifier (>= 1.3.0) web-console (>= 3.3.0) + will_paginate + will_paginate-bootstrap RUBY VERSION ruby 2.4.4p296 BUNDLED WITH - 1.16.2 + 2.0.1 diff --git a/README.md b/README.md index 7e19680a..60003e36 100644 --- a/README.md +++ b/README.md @@ -17,3 +17,249 @@ Run the specs with `rspec` Run the server with `rails s` View the site at http://localhost:3000 + +# Backend + +## Add pagination to index page, to display 5 dogs per page + +app/controllers/dogs_controller.rb + +```ruby +@dogs = Dog.paginate(page: params[:page], :per_page => 5) +``` + +app/views/_dogs.html.erb +```ruby +<%= will_paginate @dogs, renderer: BootstrapPagination::Rails %> +``` +## Add the ability to for a user to input multiple dog images on an edit form or new dog form + +app/views/_form.html.erb +```ruby +<%= f.input :images, as: :file, :input_html => { :multiple => true } %> +``` + +app/controllers/dogs_controller.rb +```ruby + def dog_params + params.require(:dog).permit(:name, :description, images: []) + end +``` + +## Associate dogs with owners + +app/models/dog.rb +```ruby + belongs_to :owner, optional: true, + primary_key: :id, + foreign_key: :owner_id, + class_name: 'User' +``` + +## Allow editing only by owner +app/controllers/dogs_controller.rb +```ruby + before_action :require_login, only: [:new, :create] +``` + +app/controllers/application_controller.rb +```ruby +def require_login + redirect_to dogs_url unless current_user + end +``` +app/views/show.html.erb +```ruby +<% if current_user && current_user.id == @dog.owner_id %> + <%= link_to "Edit #{@dog.name}'s Profile", edit_dog_path %> + <%= link_to "Delete #{@dog.name}'s Profile", dog_path, method: :delete, data: { confirm: 'Are you sure?' } %> + <% end %> +``` + +## Allow users to like other dogs (not their own) + +app/controller/likes_controller.rb +```ruby +class LikesController < ApplicationController + before_action :require_login + + def create + @like = Like.new(like_params) + @like.liker_id = current_user.id + @like.dog_id = params[:dog_id] + + respond_to do |format| + if @like.save + @dog = Dog.find(params[:dog_id]) + + format.html { redirect_to @dog } + format.json { render :show, status: :created, location: @dog } + + else + format.json { render json: @like.errors.full_messages, status: 422 } + end + end + + end + + def destroy + @like = Like.find(params[:id]) + @dog = Dog.find(@like.dog_id) + @like.destroy + + respond_to do |format| + format.html { redirect_to @dog } + end + end + + private + def like_params + params.permit(:dog_id, :liker_id) + end +end +``` + +app/views/show.html.erb +```ruby + <% if current_user && @dog.owner_id != current_user.id %> + <% if @like %> + <%= link_to "Unlike", like_url(@like.id), method: :delete %> + <% else %> + <%= link_to "Like", dog_likes_url(@dog), method: :post %> + <% end %> + <% end %> +``` + +## Allow sorting the index page by number of likes in the last hour +app/controllers/dogs_controller.rb +```ruby + def index + if params[:sort_params] + subquery = Like.select(:id, :dog_id, :user_id).where(created_at: (Time.now - 1.hour)..Time.now) + @dogs = Dog.paginate(page: params[:page], :per_page => 5) + .joins("LEFT JOIN (#{subquery.to_sql}) AS likes ON dogs.id = likes.dog_id") + .group(:id) + .order("count(likes.id) desc") + else + @dogs = Dog.paginate(page: params[:page], :per_page => 5) + end + end +``` + + +## Display the ad.jpg image after every 2 dogs in the index page + +app/views/_thumbnail.html.erb +```ruby +<% if dog_counter % 2 == 1 %> +
<%= @dog.description %>
+<%= @dog.description %>
+<%= @dog.description %>
+