Skip to content

Commit

Permalink
Merge pull request #45 from jmkoni/average-ratings
Browse files Browse the repository at this point in the history
Add averages to courses index
  • Loading branch information
jmkoni authored Jun 19, 2019
2 parents 89f39fc + 4d0b92f commit ff497a2
Show file tree
Hide file tree
Showing 21 changed files with 389 additions and 199 deletions.
3 changes: 1 addition & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,11 @@ gem 'execjs'
gem 'filterrific'
gem 'jbuilder', '~> 2.5'
gem 'jquery-rails'
gem 'kaminari'
gem 'mini_racer'
gem 'sass-rails', '~> 5.0'
gem 'turbolinks', '~> 5'
gem 'uglifier', '>= 1.3.0'
gem 'will_paginate'
gem 'will_paginate-bootstrap4'

# Documentation
gem 'simplecov-formatter-badge', require: false
Expand Down
18 changes: 13 additions & 5 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,18 @@ GEM
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
json (2.2.0)
kaminari (1.1.1)
activesupport (>= 4.1.0)
kaminari-actionview (= 1.1.1)
kaminari-activerecord (= 1.1.1)
kaminari-core (= 1.1.1)
kaminari-actionview (1.1.1)
actionview
kaminari-core (= 1.1.1)
kaminari-activerecord (1.1.1)
activerecord
kaminari-core (= 1.1.1)
kaminari-core (1.1.1)
launchy (2.4.3)
addressable (~> 2.3)
libv8 (7.3.492.27.1)
Expand Down Expand Up @@ -325,9 +337,6 @@ GEM
websocket-driver (0.7.0)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.3)
will_paginate (3.1.7)
will_paginate-bootstrap4 (0.2.2)
will_paginate (~> 3.0, >= 3.0.0)
xpath (3.2.0)
nokogiri (~> 1.8)
yard (0.9.19)
Expand Down Expand Up @@ -360,6 +369,7 @@ DEPENDENCIES
irb
jbuilder (~> 2.5)
jquery-rails
kaminari
launchy
listen (>= 3.0.5, < 3.2)
memory_profiler
Expand Down Expand Up @@ -390,8 +400,6 @@ DEPENDENCIES
turbolinks (~> 5)
uglifier (>= 1.3.0)
web-console (>= 3.3.0)
will_paginate
will_paginate-bootstrap4
yard

RUBY VERSION
Expand Down
13 changes: 10 additions & 3 deletions app/assets/stylesheets/reviews.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

table#reviews_index td.review-truncate div {
td.notes div {
width: 200px;
white-space: nowrap;
overflow: hidden; /* <- this does seem to be required */
}

td.user div {
width: 100px;
}

td.truncate div {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
7 changes: 4 additions & 3 deletions app/controllers/courses_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ class CoursesController < ApplicationController
# GET /courses
# GET /courses.json
def index
courses = Course.all.with_averages
if params[:school_id].to_i.zero?
(@filterrific = initialize_filterrific(
Course.all.preload(:school),
courses,
params[:filterrific],
select_options: {
sorted_by: Course.options_for_sorted_by,
Expand All @@ -21,14 +22,14 @@ def index
else
set_school
(@filterrific = initialize_filterrific(
Course.preload(:school).where(school_id: @school.id),
courses.where(school_id: @school.id),
params[:filterrific],
select_options: {
sorted_by: Course.options_for_sorted_by
}
)) || return
end
@courses = @filterrific.find.page(params[:page])
@courses = @filterrific.find
end

# GET /courses/1
Expand Down
34 changes: 33 additions & 1 deletion app/models/course.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ class Course < ApplicationRecord
sorted_by
search_query
with_school_id
with_avg_rating_gte
with_avg_difficulty_lte
with_avg_work_lte
]
)

Expand Down Expand Up @@ -56,6 +59,12 @@ class Course < ApplicationRecord
order(Arel.sql("LOWER(courses.number) #{direction}"))
when /^school_/
order(Arel.sql("LOWER(schools.name) #{direction}")).includes(:school).references(:school)
when /^avg_rating_/
order(Arel.sql("avg_rating #{direction}"))
when /^avg_difficulty_/
order(Arel.sql("avg_difficulty #{direction}"))
when /^avg_work_/
order(Arel.sql("avg_work #{direction}"))
else
raise(ArgumentError, "Invalid sort option: #{sort_option.inspect}")
end
Expand All @@ -65,6 +74,26 @@ class Course < ApplicationRecord
where(school_id: [*school_ids])
}

scope :with_avg_rating_gte, ->(ref_num) {
having('avg(reviews.rating) >= ?', ref_num)
}

scope :with_avg_difficulty_lte, ->(ref_num) {
having('avg(reviews.difficulty) <= ?', ref_num)
}

scope :with_avg_work_lte, ->(ref_num) {
having('avg(reviews.work_required) <= ?', ref_num)
}

scope :with_averages, -> {
select('courses.*,
avg(reviews.rating) as avg_rating,
avg(reviews.difficulty) as avg_difficulty,
avg(reviews.work_required) as avg_work')
.left_joins(:reviews, :school)
.group('courses.id, schools.id')
}
def full_number
"#{department} #{number}"
end
Expand All @@ -83,7 +112,10 @@ def self.options_for_sorted_by
['Department (a-z)', 'department_asc'],
['Department (z-a)', 'department_desc'],
['School (a-z)', 'school_name_asc'],
['School (z-a)', 'school_name_desc']
['School (z-a)', 'school_name_desc'],
['Average Rating (highest first)', 'avg_rating_desc'],
['Average Work Required (lowest first)', 'avg_work_asc'],
['Average Difficulty (lowest first)', 'avg_difficulty_asc']
]
end
end
Expand Down
85 changes: 45 additions & 40 deletions app/views/courses/_list.html.erb
Original file line number Diff line number Diff line change
@@ -1,44 +1,49 @@
<% if courses.load.empty? %>
No courses at this time!
<% else %>
<div id="filterrific_results">
<div class="card card-body bg-light d-block p-3 my-3">
<div class="row">
<div class="col-md-10">
<%= page_entries_info courses, model: 'course', class: 'align-middle' %>
</div>
<div class="col-md-2">
<%= link_to "Reset filters", reset_filterrific_url, class: 'btn btn-secondary align-middle' %>
</div>
<div id="filterrific_results">
<div class="card card-body bg-light d-block p-3 my-3">
<div class="row">
<div class="col-md-10">
<% if courses.load.empty? %>
No courses at this time!
<% else %>
Displaying <strong><%= pluralize(courses.size, 'course') %></strong>
<% end %>
</div>
<div class="col-md-2">
<%= link_to "Reset filters", reset_filterrific_url, class: 'btn btn-secondary align-middle' %>
</div>
<%= render_filterrific_spinner %>
</div>
<table class="table table-hover table-sm table-responsive">
<thead class="thead-light">
<%= render_filterrific_spinner %>
</div>
<table class="table table-hover table-sm table-responsive">
<thead class="thead-light">
<tr>
<th scope="col"><%= filterrific_sorting_link(@filterrific, :name) %></th>
<th scope="col"><%= filterrific_sorting_link(@filterrific, :number) %></th>
<th scope="col"><%= filterrific_sorting_link(@filterrific, :department) %></th>
<th scope="col"><%= filterrific_sorting_link(@filterrific, :school) %></th>
<th scope="col"><%= filterrific_sorting_link(@filterrific, :avg_rating) %></th>
<th scope="col"><%= filterrific_sorting_link(@filterrific, :avg_difficulty) %></th>
<th scope="col"><%= filterrific_sorting_link(@filterrific, :avg_work) %></th>
<th scope="col" colspan="3"></th>
</tr>
</thead>

<tbody>
<% courses.each do |course| %>
<tr>
<th scope="col"><%= filterrific_sorting_link(@filterrific, :name) %></th>
<th scope="col"><%= filterrific_sorting_link(@filterrific, :number) %></th>
<th scope="col"><%= filterrific_sorting_link(@filterrific, :department) %></th>
<th scope="col"><%= filterrific_sorting_link(@filterrific, :school) %></th>
<th scope="col" colspan="3"></th>
<td><%= link_to course.name, school_course_path(id: course.id, school_id: course.school.id) %></td>
<td><%= course.number %></td>
<td><%= course.department %></td>
<td><%= link_to course.school.name, school_path(id: course.school) %></td>
<td><%= course.avg_rating.round(1) %></td>
<td><%= course.avg_difficulty.round(1) %></td>
<td><%= course.avg_work.round(1) %></td>
<% if can? :edit, course %>
<td><%= link_to 'Edit', edit_school_course_path(id: course.id, school_id: course.school.id) %></td>
<td><%= link_to 'Destroy', school_course_path(id: course.id, school_id: course.school.id), method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% end %>
</tr>
</thead>

<tbody>
<% courses.each do |course| %>
<tr>
<td><%= link_to course.name, school_course_path(id: course.id, school_id: course.school.id) %></td>
<td><%= course.number %></td>
<td><%= course.department %></td>
<td><%= link_to course.school.name, school_path(id: course.school) %><td>
<% if can? :edit, course %>
<td><%= link_to 'Edit', edit_school_course_path(id: course.id, school_id: course.school.id) %></td>
<td><%= link_to 'Destroy', school_course_path(id: course.id, school_id: course.school.id), method: :delete, data: { confirm: 'Are you sure?' } %></td>
<% end %>
</tr>
<% end %>
</tbody>
</table>
</div>
<%= will_paginate courses, renderer: WillPaginate::ActionView::BootstrapLinkRenderer %>
<% end %>
<% end %>
</tbody>
</table>
</div>
20 changes: 20 additions & 0 deletions app/views/courses/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,26 @@
</div>
</div>
</div>
<div class="row">
<div class="col-md-3">
<div class="form-group">
<label class="font-weight-bold">Average rated higher than</label>
<%= f.number_field(:with_avg_rating_gte) %>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label class="font-weight-bold">Average difficulty lower than</label>
<%= f.number_field(:with_avg_difficulty_lte) %>
</div>
</div>
<div class="col-md-3">
<div class="form-group">
<label class="font-weight-bold">Average work required lower than</label>
<%= f.number_field(:with_avg_work_lte) %>
</div>
</div>
</div>
<% end %>
</div>

Expand Down
2 changes: 1 addition & 1 deletion app/views/devise/shared/_error_messages.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<%= I18n.t("errors.messages.not_saved",
count: resource.errors.count,
resource: resource.class.model_name.human.downcase)
%>
%>
</h2>
<ul>
<% resource.errors.full_messages.each do |message| %>
Expand Down
3 changes: 3 additions & 0 deletions app/views/kaminari/_first_page.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<li class="page-item">
<%= link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, remote: remote, class: 'page-link' %>
</li>
3 changes: 3 additions & 0 deletions app/views/kaminari/_gap.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<li class='page-item disabled'>
<%= link_to raw(t 'views.pagination.truncate'), '#', class: 'page-link' %>
</li>
3 changes: 3 additions & 0 deletions app/views/kaminari/_last_page.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<li class="page-item">
<%= link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, remote: remote, class: 'page-link' %>
</li>
3 changes: 3 additions & 0 deletions app/views/kaminari/_next_page.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<li class="page-item">
<%= link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, rel: 'next', remote: remote, class: 'page-link' %>
</li>
9 changes: 9 additions & 0 deletions app/views/kaminari/_page.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<% if page.current? %>
<li class="page-item active">
<%= content_tag :a, page, data: { remote: remote }, rel: page.rel, class: 'page-link' %>
</li>
<% else %>
<li class="page-item">
<%= link_to page, url, remote: remote, rel: page.rel, class: 'page-link' %>
</li>
<% end %>
17 changes: 17 additions & 0 deletions app/views/kaminari/_paginator.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<%= paginator.render do %>
<nav>
<ul class="pagination">
<%= first_page_tag unless current_page.first? %>
<%= prev_page_tag unless current_page.first? %>
<% each_page do |page| %>
<% if page.left_outer? || page.right_outer? || page.inside_window? %>
<%= page_tag page %>
<% elsif !page.was_truncated? -%>
<%= gap_tag %>
<% end %>
<% end %>
<%= next_page_tag unless current_page.last? %>
<%= last_page_tag unless current_page.last? %>
</ul>
</nav>
<% end %>
3 changes: 3 additions & 0 deletions app/views/kaminari/_prev_page.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<li class="page-item">
<%= link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, rel: 'prev', remote: remote, class: 'page-link' %>
</li>
Loading

0 comments on commit ff497a2

Please sign in to comment.