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

Levelbuilders can edit courses #15167

Merged
merged 3 commits into from May 18, 2017
Merged

Levelbuilders can edit courses #15167

merged 3 commits into from May 18, 2017

Conversation

Bjvanminnen
Copy link
Contributor

@Bjvanminnen Bjvanminnen commented May 17, 2017

This PR allows level builders to add localizeable text to courses, as well as to set what scripts are in them. Ideally I'd get this into today's DTP so that we can start creating a couple of courses.

The PR could still use some additional test coverage that I'm going to work on in a follow on PR.

image

i18n = File.exist?(courses_yml) ? YAML.load_file(courses_yml) : {}

i18n.deep_merge!({'en' => {'data' => {'course' => {'name' => {name => course_strings.to_h}}}}})
File.write(courses_yml, "# Autogenerated scripts locale file.\n" + i18n.to_yaml(line_width: -1))
Copy link
Contributor

Choose a reason for hiding this comment

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

We have this pattern repeated in a number of different models. I wonder if it makes sense to pull it out into a concern or its own model (not ActiveRecord-backed).

I know this is copying over existing code, but this also isn't thread safe.

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 attempted to clean up some of the existing usages (for scripts.en.yml) in the past, and found it quite challenging. I think there is probably opportunity to make this cleaner, but that it's more work than I'm willing to put in right now.

Non-thread safe is a good point, though again this is already a problem with our existing usages for scripts.en.yml (the good news is we expect courses to be edit even more infrequently than scripts).

# @param scripts [Array<String>] - Updated list of names of scripts in this course
# @param course_strings[Hash{String => String}]
def update_and_persist(scripts, course_strings)
Course.update_strings(name, course_strings)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why does this need to be static?

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 made it static because we're updating a file (courses.en.yml) that is shared amongst all courses.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure I follow. Making it static doesn't provide any additional thread safety. As an instance method you don't need to pass in name. No strong preference here, just trying to understand.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I wasn't doing it for thread safety. My intent was conceptual clarity. Strings for a course are all stored in a single file, so conceptually it made sense for me to have string persistence be a static method on the Course model rather than a method on the course instance.

# the set of scripts that are in the course, then writes out our serialization
# @param scripts [Array<String>] - Updated list of names of scripts in this course
# @param course_strings[Hash{String => String}]
def update_and_persist(scripts, course_strings)
Copy link
Contributor

Choose a reason for hiding this comment

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

Not immediately clear that this will mutate scripts. I don't think there's too much harm, but a bit of a weird side effect.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe name it more clearly, something like update_and_persist_scripts?

@@ -43,7 +43,25 @@ def create
end
end

def update
course = Course.find_by_name!(params[:course_name])
course.update_and_persist(params[:scripts], i18n_params)
Copy link
Contributor

Choose a reason for hiding this comment

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

A pattern we use elsewhere is to have an after_save :write_serialization vs. calling the serialization explicitly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That works in places like level, because the serialization is captured entirely in the level object. Course (and script) are weird in that in addition to serialization to course_name.course, we also need to save our localizeable data to a yml file.

We could save our localizeable data explicitly, and then have it do the serialization to course_name.course in an after_save.

Copy link
Contributor

Choose a reason for hiding this comment

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

Note that you can have multiple after_save methods in a model.

name: 'this-course',
script_names: ['script1', 'script2']
}.to_json
# File.any_instance.stub(:read) { serialization }
Copy link
Contributor

Choose a reason for hiding this comment

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

Not used?

def update_and_persist(scripts, course_strings)
Course.update_strings(name, course_strings)
update_scripts(scripts)
save
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you want the non-bang save here? If so, add a @return to the function doc, explaining the save may fail.

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 think I probably want the bang save.

Copy link
Contributor

@aoby aoby left a comment

Choose a reason for hiding this comment

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

This generally LGTM, though I'm not super familiar with this area of the codebase. I agree with @joshlory it would be nice to consolidate the duplicate code into a concern if possible (could be a future PR)

@Bjvanminnen Bjvanminnen merged commit d07be7b into staging May 18, 2017
@Bjvanminnen Bjvanminnen deleted the editCourse branch May 18, 2017 19:52
This was referenced May 18, 2017
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