Skip to content
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

Merged
merged 3 commits into from May 17, 2017
Merged

Can create new courses #15148

merged 3 commits into from May 17, 2017

Conversation

Bjvanminnen
Copy link
Contributor

This PR makes it so that we can create new courses (by going to /courses/new on LB). It also enforces some validation on the name, which is stricter than the name for PLC courses (in part because we will need to serialize these in ways that wont happen with PLC).

@Bjvanminnen Bjvanminnen requested review from aoby and joshlory May 17, 2017 16:19
@joshlory joshlory self-assigned this May 17, 2017
Copy link
Contributor

@joshlory joshlory left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for all the comments! Feel free to ignore the style comments, but we should add authorization to the CoursesController#create action.

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is necessary — find_by_name! should raise if the course isn't found.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i believe you are right

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

find_by_name! raises if the course is not found, but we also want to raise if we found a course, but it is a regular course rather than a plc_course

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Could change find_by_name! -> find_by_name for clarity.


def new
render 'new'
end
Copy link
Contributor

Choose a reason for hiding this comment

The 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 😛.

end

def create
course = Course.new(name: params.require(:course).require(:name))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth pulling this out to a private course_params method, and re-using in the show action? For example: ScriptsController#script_params.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They use two different sets of params? show takes params[:course_name], where as here we have params[:course][:name]

end
end

test "should allow uppercase letters if it is a plc course" do
Copy link
Contributor

Choose a reason for hiding this comment

The 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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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).


# 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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as in Script, this is redundant with the above name validation. If we really want defense-in-depth maybe we should pull this validator out as a concern?

end
end

validates_with CourseNameValidator
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this format instead of validates :name (with unless: :plc_course)? It looks like there's common functionality in Script we could maybe combine into a single concern. If we want to start standardizing on this format for all names that appear in URLs...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also for custom validators that are only used in a single, it's simpler to just define a method (example). These ActiveModel::Validator classes are typically used for validations shared across models, for example.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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.

@@ -1,4 +1,6 @@
class CoursesController < ApplicationController
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auth for modify actions?

if course.save
redirect_to action: :edit, course_name: course.name
else
render 'new', locals: {error_messages: course.errors.full_messages}
Copy link
Contributor

@aoby aoby May 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A common way of doing this is to set @course, and have the form in the view be form_for @course. That way any params are saved between attempts, and errors are already on the @course object and don't need to be passed separately.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or if you prefer it to be explicit, pass course as a local, do form_for course, and inspect course.errors

end
end

validates_with CourseNameValidator
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also for custom validators that are only used in a single, it's simpler to just define a method (example). These ActiveModel::Validator classes are typically used for validations shared across models, for example.

@Bjvanminnen
Copy link
Contributor Author

@aoby @joshlory I believe I've addressed all feedback.

else
render 'new', locals: {course: course}
end
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this action is missing test coverage?

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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.

unless: :plc_course,
with: /\A[a-z0-9\-]+\z/,
message: 'can only contain lowercase letters, numbers and dashes'
}
Copy link
Contributor

Choose a reason for hiding this comment

The 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 Script.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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

@Bjvanminnen Bjvanminnen merged commit 80f57e6 into staging May 17, 2017
@Bjvanminnen Bjvanminnen deleted the newCourse branch May 17, 2017 22:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants