-
Notifications
You must be signed in to change notification settings - Fork 479
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can create new courses #15148
Can create new courses #15148
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
class CoursesController < ApplicationController | ||
before_action :require_levelbuilder_mode, except: [:index, :show] | ||
|
||
def index | ||
@recent_courses = current_user.try(:recent_courses) | ||
@is_teacher = !!(current_user && current_user.teacher?) | ||
|
@@ -8,9 +10,16 @@ def index | |
end | ||
|
||
def show | ||
course_name = params[:course_name].tr('-', '_').titleize | ||
course = Course.find_by_name(course_name) | ||
raise ActiveRecord::RecordNotFound unless course | ||
course = Course.find_by_name(params[:course_name]) | ||
unless course | ||
# PLC courses have different ways of getting to name. ideally this goes | ||
# away eventually | ||
course_name = params[:course_name].tr('-', '_').titleize | ||
course = Course.find_by_name!(course_name) | ||
# only support this alternative course name for plc courses | ||
raise ActiveRecord::RecordNotFound unless course.plc_course | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is necessary — There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i believe you are right There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. Could change |
||
end | ||
|
||
if course.plc_course | ||
authorize! :show, Plc::UserCourseEnrollment | ||
user_course_enrollments = [Plc::UserCourseEnrollment.find_by(user: current_user, plc_course: course.plc_course)] | ||
|
@@ -20,4 +29,21 @@ def show | |
|
||
render 'show', locals: {course: course} | ||
end | ||
|
||
def new | ||
render 'new' | ||
end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: We should standardize on whether we want to include these boilerplate action definitions if they are only rendering the default view. I know you prefer explicit, but Rails is CoC by default 😛. |
||
|
||
def create | ||
course = Course.new(name: params.require(:course).require(:name)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Worth pulling this out to a private There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They use two different sets of params? |
||
if course.save | ||
redirect_to action: :edit, course_name: course.name | ||
else | ||
render 'new', locals: {error_messages: course.errors.full_messages} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A common way of doing this is to set There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've been trying to avoid using instance variables in my views, as I find them much more difficult to follow than explicitly passing things in via locals. This might be a case where there's a good argument for doing it the way you say. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or if you prefer it to be explicit, pass |
||
end | ||
end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like this action is missing test coverage? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure how interesting this method is to test. I might add a quick and dirty test in a future PR. |
||
|
||
def edit | ||
render text: 'Not yet implemented' | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,32 @@ class Course < ApplicationRecord | |
has_one :plc_course, class_name: 'Plc::Course' | ||
has_many :course_scripts, -> {order('position ASC')} | ||
|
||
validates :name, | ||
presence: true, | ||
uniqueness: {case_sensitive: false} | ||
|
||
class CourseNameValidator < ActiveModel::Validator | ||
def validate(course) | ||
return if course.plc_course | ||
|
||
unless /\A[a-z0-9\-]+\z/ =~ course.name | ||
course.errors[:base] << 'can only contain lowercase letters, numbers and dashes' | ||
end | ||
end | ||
end | ||
|
||
validates_with CourseNameValidator | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why this format instead of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're way is much better than mine. I will try that approach. |
||
|
||
# As we read and write to files with the course name, to prevent directory | ||
# traversal (for security reasons), we do not allow the name to start with a | ||
# tilde or dot or contain a slash. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as in |
||
validates :name, | ||
presence: true, | ||
format: { | ||
without: /\A~|\A\.|\//, | ||
message: 'cannot start with a tilde or dot or contain slashes' | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be good to have this de-duped against the name validation in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using a concern to do this may be easier to do than I thought. I will explore doing this in a follow on PR |
||
|
||
def summarize | ||
{ | ||
name: name, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
- error_messages = local_assigns[:error_messages] | ||
|
||
- if error_messages.try(:any?) | ||
#error_explanation | ||
%h2 | ||
= pluralize(error_messages.count, 'error') | ||
prohibited this course from being saved: | ||
%ul | ||
- error_messages.each do |msg| | ||
%li= msg | ||
|
||
%h1= t('crud.new_model', model: Course.model_name.human) | ||
= form_for(:course, {url: courses_path}) do |f| | ||
.field | ||
= f.label :name | ||
= f.text_field :name | ||
%button.btn.btn-primary{type: 'submit', style: 'margin: 0'} Save Changes |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,25 @@ | ||
require 'test_helper' | ||
|
||
class CourseTest < ActiveSupport::TestCase | ||
# test "the truth" do | ||
# assert true | ||
# end | ||
test "should allow valid course names" do | ||
create(:course, name: 'valid-name') | ||
end | ||
|
||
test "should not allow uppercase letters in course name" do | ||
assert_raises ActiveRecord::RecordInvalid do | ||
create(:course, name: 'UpperCase') | ||
end | ||
end | ||
|
||
test "should not allow spaces in course name" do | ||
assert_raises ActiveRecord::RecordInvalid do | ||
create(:course, name: 'spaced out') | ||
end | ||
end | ||
|
||
test "should allow uppercase letters if it is a plc course" do | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are we tracking the debt to unify & redirect professional learning courses that don't match the format? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's somewhat less important for these to be unified, given that PLC courses aren't being serialized to a file based on their name (unlike regular courses in the near future). |
||
course = Course.new(name: 'PLC Course') | ||
course.plc_course = Plc::Course.new(course: course) | ||
course.save! | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Auth for modify actions?