diff --git a/schedules/.gitignore b/schedules/.gitignore
index b5a9845bb1470020efc0656e18054892284371b8..e81eba5ef246b6382d4d6cc35834a6b64efa119f 100644
--- a/schedules/.gitignore
+++ b/schedules/.gitignore
@@ -26,3 +26,6 @@
/node_modules
yarn-debug.log*
.yarn-integrity
+
+coverage
+subjects
diff --git a/schedules/app/controllers/api/course_sections_controller.rb b/schedules/app/controllers/api/course_sections_controller.rb
index 105589038e9735a54e4103cfb6aa2ea2dd75c2f1..5318093d7a601650f999e4cbcf9b3180b75d7826 100644
--- a/schedules/app/controllers/api/course_sections_controller.rb
+++ b/schedules/app/controllers/api/course_sections_controller.rb
@@ -11,9 +11,10 @@ class API::CourseSectionsController < ApplicationController
param :instructor, String, desc: "Get course sections being taught by this instructor"
def index
@sections = CourseSection
- .select('course_sections.*, courses.semester_id, instructors.name AS instructor_name')
- .joins(:course).where('courses.semester_id = ?', @semester.id)
- .joins(:instructor)
+ .where(semester: @semester)
+ .joins(:course)
+ .joins(:instructor)
+ .select('course_sections.*, instructors.name AS instructor_name')
if params.key?(:course_id)
@sections = @sections.where(course_id: params[:course_id])
diff --git a/schedules/app/controllers/api/courses_controller.rb b/schedules/app/controllers/api/courses_controller.rb
index 3408e3bcfddfe82010badbf1248dbb4676a7349a..8fda1aa6fbe0598c2b14ff45ae9a0b074254ceca 100644
--- a/schedules/app/controllers/api/courses_controller.rb
+++ b/schedules/app/controllers/api/courses_controller.rb
@@ -8,7 +8,7 @@ class API::CoursesController < ApplicationController
param :subject, String, desc: 'Course subject, e.g. "CS" or "ACCT"'
param :course_number, Integer, desc: 'Course number, e.g. "112"'
def index
- @courses = Course.where(semester_id: params[:semester_id])
+ @courses = Course.all
if params.key?(:subject)
@courses = @courses.where("UPPER(courses.subject) LIKE ?", "%#{params[:subject]}%")
@@ -21,7 +21,6 @@ class API::CoursesController < ApplicationController
result = @courses.map do |c|
{
id: c.id,
- semester_id: c.semester_id,
subject: c.subject,
course_number: c.course_number,
description: c.description,
diff --git a/schedules/app/controllers/courses_controller.rb b/schedules/app/controllers/courses_controller.rb
index 988aaf7e20d99fb32c192e350087ba5d6cd292e1..53dfa4f740112fd03e4daa40a051f43bc57d788c 100644
--- a/schedules/app/controllers/courses_controller.rb
+++ b/schedules/app/controllers/courses_controller.rb
@@ -2,18 +2,6 @@ class CoursesController < ApplicationController
def show
# Load the course with the id passed in the URL.
@course = Course.find_by_id(params[:id])
-
- # If the user changes the semester while looking at a course,
- # we need to display the page for the course with the same subject and course number
- # in that semester.
- unless @course.semester == @semester
- # find the course we should redirect to
- @course = Course.find_by(subject: @course.subject, course_number: @course.course_number, semester: @semester)
-
- # redirect to the url for that course
- redirect_to course_url(@course)
- end
-
- @sections = @course.course_sections
+ @sections = @course.course_sections.where(semester: @semester)
end
end
diff --git a/schedules/app/controllers/instructors_controller.rb b/schedules/app/controllers/instructors_controller.rb
index 3a2bd4be460f76010dc1168211e59aaff10efc8e..c7e067815d1fd695b490ce6d0aa8506aa85d62b9 100644
--- a/schedules/app/controllers/instructors_controller.rb
+++ b/schedules/app/controllers/instructors_controller.rb
@@ -7,7 +7,7 @@ class InstructorsController < ApplicationController
@instructor = Instructor.find_by_id(params[:id])
# find the courses being taught this semester
- sections = CourseSection.where(instructor: @instructor).joins(course: :semester).where("semesters.id = ?", @semester.id)
+ sections = CourseSection.where(instructor: @instructor, semester: @semester)
@courses = Course.build_set(sections)
# build the list of courses the instructor has taught in the past
diff --git a/schedules/app/helpers/search_helper.rb b/schedules/app/helpers/search_helper.rb
index 486773a9063ae23da762a6620e81fecd3ff260ee..ce0dedf97a557eae7a6693f92287413d8945f7a9 100644
--- a/schedules/app/helpers/search_helper.rb
+++ b/schedules/app/helpers/search_helper.rb
@@ -27,15 +27,15 @@ module SearchHelper
def self.fetchall(search_string, sort_mode: :auto, semester: :fall2018)
query_data = GenericQueryData.new(search_string, sort_mode, semester)
models = []
- models += fetch_instructors query_data
- models += fetch_courses query_data
+ models += fetch_instructors(query_data)
+ models += fetch_courses(query_data)
build_list(models)
end
def self.fetch_instructors(query_data)
Instructor.from_name(Instructor.select("instructors.*, COUNT(courses.id) AS section_count").from("course_sections"), query_data.search_string)
.joins("LEFT OUTER JOIN instructors ON instructors.id = course_sections.instructor_id")
- .joins("LEFT OUTER JOIN courses ON courses.id = course_sections.course_id AND courses.semester_id = #{query_data.semester.id}")
+ .joins("LEFT OUTER JOIN courses ON courses.id = course_sections.course_id AND course_sections.semester_id = #{query_data.semester.id}")
.group("instructors.id").all
end
@@ -46,7 +46,7 @@ module SearchHelper
base_query = Course.select("courses.*, count(course_sections.id) AS section_count")
.left_outer_joins(:course_sections)
.having("count(course_sections.id) > 0")
- .where("courses.semester_id = ?", query_data.semester)
+ .where("course_sections.semester_id = ?", query_data.semester)
.group("courses.id")
subj = nil
diff --git a/schedules/app/models/course.rb b/schedules/app/models/course.rb
index bcd3081e9a3fcc494937cc1a9086c22efa65c270..330b42758e04ceb5acfa97082cdc3b69a46d511c 100644
--- a/schedules/app/models/course.rb
+++ b/schedules/app/models/course.rb
@@ -1,13 +1,10 @@
# Contains logic regarding the +Course+ model.
class Course < ApplicationRecord
- # Each course belongs to a +Semester+
- belongs_to :semester
has_many :course_sections
# Ensure all necessary are fields present.
validates :course_number, presence: true
validates :subject, presence: true
- validates :semester_id, presence: true
def full_name
"#{subject} #{course_number}"
diff --git a/schedules/app/models/course_section.rb b/schedules/app/models/course_section.rb
index 2f4db5892cabc7f0b3cadb2ace5ac25dd2594ec1..8eb9c1a8dbcce799f050ac593a33ed65735845d6 100644
--- a/schedules/app/models/course_section.rb
+++ b/schedules/app/models/course_section.rb
@@ -3,12 +3,16 @@ class CourseSection < ApplicationRecord
# Each +CourseSection+ belongs to a +Course+ and an +Instructor+.
belongs_to :course
belongs_to :instructor
+
+ # Each course belongs to a +Semester+
+ belongs_to :semester
# Ensure all necessary fields are present.
validates :name, presence: true
validates :crn, presence: true
validates :title, presence: true
validates :course_id, presence: true
+ validates :semester_id, presence: true
def overlaps?(other)
t1_start, t1_end = Time.parse(start_time), Time.parse(end_time)
@@ -18,7 +22,7 @@ class CourseSection < ApplicationRecord
end
def self.latest_by_crn(crn)
- where(crn: crn).min_by { |s| s.course.semester.id }
+ where(crn: crn).min_by { |s| s.semester.id }
end
# Select all course sections that have an instructor that matches the given name
diff --git a/schedules/app/models/schedule.rb b/schedules/app/models/schedule.rb
index 6e6d7967428c56dd384245b7aad05f7a312f90ac..49ea5c55536b17afc79e1df07e8499a3b67a8b69 100644
--- a/schedules/app/models/schedule.rb
+++ b/schedules/app/models/schedule.rb
@@ -95,7 +95,7 @@ class Schedule
# @return [Array]
def exdates_for_section(section)
# Generate exdates for all closures in a semester
- exdates = Closure.where(semester: section.course.semester).map { |closure|
+ exdates = Closure.where(semester: section.semester).map { |closure|
generate_exdate(closure.date.to_formatted_s(:number), section.start_time)
}
diff --git a/schedules/app/views/shared/_course.html.erb b/schedules/app/views/shared/_course.html.erb
index 1129e3eb2adb42b5bd25df0a9a2637c9d179ec76..40100afd776cbcbe5bf0bad798df5c23b6751071 100644
--- a/schedules/app/views/shared/_course.html.erb
+++ b/schedules/app/views/shared/_course.html.erb
@@ -1,5 +1,11 @@
<% expanded = false unless defined? expanded %>
+<% if defined?(@instructor) %>
+ <% sections = course.course_sections.where(instructor: @instructor, semester: @semester).order(:name) %>
+<% else %>
+ <% sections = course.course_sections.where(semester: @semester).order(:name) %>
+<% end %>
+
<%= course.description %>
@@ -42,11 +48,7 @@
">
- <% if defined?(@instructor) %>
- <%= render partial: 'shared/section', collection: course.course_sections.where(instructor: @instructor).order(:name), locals: { course: course } %>
- <% else %>
- <%= render partial: 'shared/section', collection: course.course_sections.order(:name), locals: { course: course } %>
- <% end %>
+ <%= render partial: 'shared/section', collection: sections, locals: { course: course } %>
diff --git a/schedules/db/migrate/20190210152552_remove_semester_fk_from_course.rb b/schedules/db/migrate/20190210152552_remove_semester_fk_from_course.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4489ffeda9a92aac20dd9bec1249d4a74adb68e5
--- /dev/null
+++ b/schedules/db/migrate/20190210152552_remove_semester_fk_from_course.rb
@@ -0,0 +1,6 @@
+class RemoveSemesterFkFromCourse < ActiveRecord::Migration[5.1]
+ def change
+ remove_column :courses, :semester_id
+ add_reference :course_sections, :semester, foreign_key: true
+ end
+end
diff --git a/schedules/db/schema.rb b/schedules/db/schema.rb
index 219b2a4637d1f20bef01231e11a456a8bba619e2..c964202de767a33ba585e9003709b0298c1a3492 100644
--- a/schedules/db/schema.rb
+++ b/schedules/db/schema.rb
@@ -10,14 +10,11 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20180927140017) do
-
- # These are extensions that must be enabled in order to support this database
- enable_extension "plpgsql"
+ActiveRecord::Schema.define(version: 20190210152552) do
create_table "closures", force: :cascade do |t|
t.date "date"
- t.bigint "semester_id"
+ t.integer "semester_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["semester_id"], name: "index_closures_on_semester_id"
@@ -38,25 +35,25 @@ ActiveRecord::Schema.define(version: 20180927140017) do
t.string "campus"
t.string "notes"
t.integer "size_limit"
- t.bigint "course_id"
+ t.integer "course_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
- t.bigint "instructor_id"
+ t.integer "instructor_id"
+ t.integer "semester_id"
t.index ["course_id"], name: "index_course_sections_on_course_id"
t.index ["instructor_id"], name: "index_course_sections_on_instructor_id"
+ t.index ["semester_id"], name: "index_course_sections_on_semester_id"
end
create_table "courses", force: :cascade do |t|
t.string "subject"
t.string "course_number"
- t.bigint "semester_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "description"
t.string "credits"
t.string "title"
t.string "prereqs"
- t.index ["semester_id"], name: "index_courses_on_semester_id"
end
create_table "instructors", force: :cascade do |t|
@@ -72,8 +69,4 @@ ActiveRecord::Schema.define(version: 20180927140017) do
t.datetime "updated_at", null: false
end
- add_foreign_key "closures", "semesters"
- add_foreign_key "course_sections", "courses"
- add_foreign_key "course_sections", "instructors"
- add_foreign_key "courses", "semesters"
end
diff --git a/schedules/db/seeds.rb b/schedules/db/seeds.rb
index 20612b8a0ddf157459d5bec43f73cd7b70f4e6d9..57c3b48949180e1f890d49c8a144869be282c591 100644
--- a/schedules/db/seeds.rb
+++ b/schedules/db/seeds.rb
@@ -22,7 +22,7 @@ def parse_courses(subjects)
courses
end
-def load_courses(courses, semester)
+def load_courses(courses)
insert_hashes = courses.map do |course|
{
subject: course[:subject],
@@ -31,7 +31,6 @@ def load_courses(courses, semester)
credits: course[:credits],
description: course[:description],
prereqs: course[:prereqs],
- semester: semester
}
end
@@ -64,8 +63,7 @@ def load_sections(sections_in, semester)
end
course = Course.find_or_create_by!(subject: section[:subj],
- course_number: section[:course_number],
- semester: semester)
+ course_number: section[:course_number])
instructor = Instructor.find_or_create_by!(name: section[:instructor])
@@ -82,7 +80,8 @@ def load_sections(sections_in, semester)
end_time: section[:end_time],
location: section[:location],
course: course,
- instructor: instructor)
+ instructor: instructor,
+ semester: semester)
end
all_sections.each { |s| CourseSection.find_or_create_by! s }
@@ -117,24 +116,23 @@ def main
[parser.parse_semesters.first]
else
# expand to include however many semesters you want
- parser.parse_semesters[0..6]
+ parser.parse_semesters[0..2]
end
- courses = nil
+ puts "\tParsing subjects..."
+ subjects = parser.parse_subjects(semesters.first[:value])
+
+ puts "\tParsing courses from catalog.gmu.edu..."
+ courses = parse_courses(subjects) if courses.nil?
+
+ puts "\tLoading courses..."
+ load_courses(courses)
+
semesters.each do |semester|
puts "#{semester[:season]} #{semester[:year]}"
db_semester = Semester.find_or_create_by!(season: semester[:season], year: semester[:year])
- puts "\tParsing subjects..."
- subjects = parser.parse_subjects(semester[:value])
-
- puts "\tParsing courses from catalog.gmu.edu..."
- courses = parse_courses(subjects) if courses.nil?
-
- puts "\tLoading courses..."
- load_courses(courses, db_semester)
-
puts "\tParsing sections from Patriot Web..."
sections_in = parse_sections(semester[:value], subjects)
diff --git a/schedules/test/controllers/api/course_sections_controller_test.rb b/schedules/test/controllers/api/course_sections_controller_test.rb
index d1d99f4ba18876f9706965e6e0805d0cddc5e10e..71f9e3f39e60f9bea06cb1d7b20fe0c99173adc4 100644
--- a/schedules/test/controllers/api/course_sections_controller_test.rb
+++ b/schedules/test/controllers/api/course_sections_controller_test.rb
@@ -2,14 +2,15 @@ require 'test_helper'
class API::CourseSectionsControllerTest < ActionDispatch::IntegrationTest
test 'should get index' do
- get api_course_sections_url course_id: courses(:cs112).id, semester_id: semesters(:fall2018).id
+ get api_course_sections_url(course_id: courses(:cs112).id,
+ semester_id: semesters(:fall2018).id)
+
assert_response :success
sections_returned = JSON.parse @response.body
num_sections = CourseSection
- .joins(course: :semester)
- .where('semesters.id = ?', semesters(:fall2018).id)
- .where(course_id: courses(:cs112).id).count
+ .where(course_id: courses(:cs112).id)
+ .where(semester: semesters(:fall2018)).count
assert_equal num_sections, sections_returned.count
end
diff --git a/schedules/test/controllers/api/courses_controller_test.rb b/schedules/test/controllers/api/courses_controller_test.rb
index c130c3e46a26dfd219900dd44339931a70519484..0dfd9cca1b14b2ee836f56b41e22f9eab41c7c57 100644
--- a/schedules/test/controllers/api/courses_controller_test.rb
+++ b/schedules/test/controllers/api/courses_controller_test.rb
@@ -2,30 +2,30 @@ require 'test_helper'
class API::CoursesControllerTest < ActionDispatch::IntegrationTest
test '#index should return all courses' do
- get api_courses_url semester_id: semesters(:fall2018).id
+ get api_courses_url
assert_response :success
courses_returned = JSON.parse @response.body
- courses_count = Course.where(semester_id: semesters(:fall2018).id).count
+ courses_count = Course.all.count
assert_equal courses_count, courses_returned.count
end
test '#index should return filtered by subject case insensitive' do
- get api_courses_url subject: "Cs", semester_id: semesters(:fall2018).id
+ get api_courses_url(subject: "Cs")
assert_response :success
courses_returned = JSON.parse @response.body
- courses_count = Course.where(subject: "CS", semester_id: semesters(:fall2018).id).count
+ courses_count = Course.where(subject: "CS").count
assert_equal courses_count, courses_returned.count
end
test '#index should return filtered by subject and course number' do
- get api_courses_url subject: "CS", course_number: "112", semester_id: semesters(:fall2018).id
+ get api_courses_url(subject: "CS", course_number: "112")
assert_response :success
courses_returned = JSON.parse @response.body
- courses_count = Course.where(subject: "CS", course_number: "112", semester_id: semesters(:fall2018).id).count
+ courses_count = Course.where(subject: "CS", course_number: "112").count
assert_equal courses_count, courses_returned.count
end
@@ -33,7 +33,7 @@ class API::CoursesControllerTest < ActionDispatch::IntegrationTest
test '#show should return course_sections for course' do
cs_112_id = courses(:cs112).id
- get api_course_url id: cs_112_id, semester_id: semesters(:fall2018).id
+ get api_course_url(id: cs_112_id)
assert_response :success
sections_returned = JSON.parse @response.body
diff --git a/schedules/test/controllers/courses_controller_test.rb b/schedules/test/controllers/courses_controller_test.rb
index e3fdb5a9cdfb9470ef2049fd56330b8bfd4573ac..489d03d592f6affbf8f4e5057f62797ec71e313f 100644
--- a/schedules/test/controllers/courses_controller_test.rb
+++ b/schedules/test/controllers/courses_controller_test.rb
@@ -7,6 +7,6 @@ class CoursesControllerTest < ActionDispatch::IntegrationTest
assert_response :success
# assert every course section is displayed
- assert_select '.section-item', c.course_sections.count
+ assert_select '.section-item', c.course_sections.where(semester: semesters(:fall2018)).count
end
end
diff --git a/schedules/test/fixtures/course_sections.yml b/schedules/test/fixtures/course_sections.yml
index a10970038461917b2f1bf2b36ad53d2913b09fed..167223d3f5009547bedeeec5c4370df7cbf28b8e 100644
--- a/schedules/test/fixtures/course_sections.yml
+++ b/schedules/test/fixtures/course_sections.yml
@@ -12,6 +12,7 @@ cs112001:
location: Innovation Hall 204
course: cs112
instructor: kinga
+ semester: fall2018
cs112002:
name: CS 112 002
@@ -25,6 +26,7 @@ cs112002:
end_time: 2:00 pm
course: cs112
instructor: luke
+ semester: fall2018
cs211001:
name: CS 211 001
@@ -36,8 +38,9 @@ cs211001:
start_time: 2:30 pm
end_time: 3:00 pm
location: ENGR 200
- course: cs211spring
+ course: cs211
instructor: otten
+ semester: spring2018
cs112001spring:
name: CS 112 001
@@ -49,8 +52,9 @@ cs112001spring:
start_time: 12:00 pm
end_time: 1:00 pm
location: Innovation Hall 204
- course: cs112spring
+ course: cs112
instructor: kinga
+ semester: spring2018
acct110001:
name: ACCT 110 001
@@ -62,5 +66,6 @@ acct110001:
start_time: 12:00 pm
end_time: 1:00 pm
location: Innovation Hall 204
- course: acct110spring
+ course: acct110
instructor: business_man
+ semester: spring2018
diff --git a/schedules/test/fixtures/courses.yml b/schedules/test/fixtures/courses.yml
index 2d1f1821f29990dcc752e3884de18c87ec60a065..1695827dc40887b97793dd4a50c11ba762371f5f 100644
--- a/schedules/test/fixtures/courses.yml
+++ b/schedules/test/fixtures/courses.yml
@@ -3,24 +3,13 @@
cs112:
subject: CS
course_number: 112
- semester: fall2018
cs211:
subject: CS
course_number: 211
- semester: fall2018
-acct110spring:
+acct110:
subject: ACCT
course_number: 110
- semester: spring2018
-cs110spring:
- subject: CS
- course_number: 110
- semester: spring2018
-
-cs112spring:
- subject: CS
- course_number: 112
- semester: spring2018
+
diff --git a/schedules/test/models/course_section_test.rb b/schedules/test/models/course_section_test.rb
index 1fb17e085a547099eb879524d49eea4a2febbecf..970600232ab7b607555ae38a03e08e19f24fab03 100644
--- a/schedules/test/models/course_section_test.rb
+++ b/schedules/test/models/course_section_test.rb
@@ -13,8 +13,9 @@ class CourseSectionTest < ActiveSupport::TestCase
CourseSection.create! name: 'Test section',
crn: '12345',
title: 'Test title',
- course_id: courses(:cs211).id,
- instructor_id: instructors(:luke).id
+ course: courses(:cs211),
+ instructor: instructors(:luke),
+ semester: semesters(:fall2018)
end
test '#with_instructor filters correctly' do
@@ -24,6 +25,6 @@ class CourseSectionTest < ActiveSupport::TestCase
test '#latest_by_crn sorts correctly' do
s = CourseSection.latest_by_crn(70192)
- assert_equal semesters(:fall2018).id, s.course.semester.id
+ assert_equal semesters(:fall2018).id, s.semester.id
end
end
diff --git a/schedules/test/models/course_test.rb b/schedules/test/models/course_test.rb
index a9819248b9296555dff75b7c31133899615d0346..d0f979a89a853872ba858c2444fa23e622002d23 100644
--- a/schedules/test/models/course_test.rb
+++ b/schedules/test/models/course_test.rb
@@ -3,15 +3,15 @@ require 'test_helper'
class CourseTest < ActiveSupport::TestCase
test 'fails with improper data' do
assert_raise do
- Course.create! course_number: nil, subject: nil, semester_id: nil
+ Course.create! course_number: nil, subject: nil
end
end
test 'creates with proper data' do
- Course.create! course_number: '112', subject: 'CS', semester_id: semesters(:fall2018).id
+ Course.create! course_number: '112', subject: 'CS'
end
test 'has correct number of sections' do
- assert_equal 2, courses(:cs112).course_sections.count
+ assert_equal 3, courses(:cs112).course_sections.count
end
end
diff --git a/schedules/test/models/semester_test.rb b/schedules/test/models/semester_test.rb
index 624cfdec1d9e4a174d211f0bb12ba09af97cad4a..9c06415791580a2fc0860c1e81fb86e6b7a91f0b 100644
--- a/schedules/test/models/semester_test.rb
+++ b/schedules/test/models/semester_test.rb
@@ -10,8 +10,4 @@ class SemesterTest < ActiveSupport::TestCase
test 'create successful' do
Semester.create!(season: 'Test', year: 'Test')
end
-
- test 'semester has correct number of courses' do
- assert_equal 2, semesters(:fall2018).courses.count
- end
end