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

Revert "Seed and serialize vocab" #38524

Merged
merged 1 commit into from
Jan 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion dashboard/app/models/course_version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
class CourseVersion < ApplicationRecord
belongs_to :course_offering
has_many :resources
has_many :vocabularies

def units
content_root_type == 'UnitGroup' ? content_root.default_scripts : [content_root]
Expand Down
5 changes: 1 addition & 4 deletions dashboard/app/models/lesson.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,9 @@ class Lesson < ApplicationRecord
has_many :levels, through: :script_levels
has_and_belongs_to_many :resources, join_table: :lessons_resources
has_and_belongs_to_many :vocabularies, join_table: :lessons_vocabularies
has_many :lessons_resources # join table. we need this association for seeding logic
has_many :objectives, dependent: :destroy

# join tables needed for seeding logic
has_many :lessons_resources
has_many :lessons_vocabularies

has_one :plc_learning_module, class_name: 'Plc::LearningModule', inverse_of: :lesson, foreign_key: 'stage_id', dependent: :destroy
has_and_belongs_to_many :standards, foreign_key: 'stage_id'

Expand Down
18 changes: 0 additions & 18 deletions dashboard/app/models/lessons_vocabulary.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,4 @@
class LessonsVocabulary < ApplicationRecord
belongs_to :lesson
belongs_to :vocabulary

# Used for seeding from JSON. Returns the full set of information needed to
# uniquely identify this object as well as any other objects it belongs to.
# If the attributes of this object alone aren't sufficient, and associated
# objects are needed, then data from the seeding_keys of those objects should
# be included as well. Ideally should correspond to a unique index for this
# model's table. See comments on ScriptSeed.seed_from_json for more context.
#
# @param [ScriptSeed::SeedContext] seed_context - contains preloaded data to use when looking up associated objects
# @return [Hash<String, String>] all information needed to uniquely identify this object across environments.
def seeding_key(seed_context)
my_lesson = seed_context.lessons.select {|l| l.id == lesson_id}.first
my_vocabulary = seed_context.vocabularies.select {|r| r.id == vocabulary_id}.first
{
'lesson.key' => my_lesson.key,
'vocabulary.key' => my_vocabulary.key
}.stringify_keys
end
end
1 change: 0 additions & 1 deletion dashboard/app/models/script.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ class Script < ApplicationRecord
lessons: [
{lesson_activities: :activity_sections},
:resources,
:vocabularies,
:objectives
]
},
Expand Down
18 changes: 0 additions & 18 deletions dashboard/app/models/vocabulary.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,8 @@
#
class Vocabulary < ApplicationRecord
has_and_belongs_to_many :lessons, join_table: :lessons_vocabularies
has_many :lessons_vocabularies
belongs_to :course_version

# Used for seeding from JSON. Returns the full set of information needed to
# uniquely identify this object as well as any other objects it belongs to.
# If the attributes of this object alone aren't sufficient, and associated
# objects are needed, then data from the seeding_keys of those objects should
# be included as well. Ideally should correspond to a unique index for this
# model's table. See comments on ScriptSeed.seed_from_json for more context.
#
# @param [ScriptSeed::SeedContext] _seed_context - contains preloaded data to use when looking up associated objects
# @return [Hash<String, String>] all information needed to uniquely identify this object across environments.
def seeding_key(_seed_context)
# Course version is also needed to identify this object, and can be looked
# up from the script/unit which this vocabulary is serialized within. If we
# were to serialize vocabulary outside of .script_json, we'd need to include
# a key respresenting the course version here.
{'vocabulary.key': key}.stringify_keys
end

def summarize_for_lesson_show
{key: key, word: display_word, definition: display_definition}
end
Expand Down
96 changes: 3 additions & 93 deletions dashboard/lib/services/script_seed.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module ScriptSeed
SeedContext = Struct.new(
:script, :lesson_groups, :lessons, :lesson_activities, :activity_sections,
:script_levels, :levels_script_levels, :levels, :resources,
:lessons_resources, :vocabularies, :lessons_vocabularies, :objectives, keyword_init: true
:lessons_resources, :objectives, keyword_init: true
)

# Produces a JSON representation of the given Script and all objects under it in its "tree", in a format specifically
Expand All @@ -42,8 +42,6 @@ def self.serialize_seeding_json(script)
sections = activities.map(&:activity_sections).flatten
resources = script.lessons.map(&:resources).flatten
lessons_resources = script.lessons.map(&:lessons_resources).flatten
vocabularies = script.lessons.map(&:vocabularies).flatten
lessons_vocabularies = script.lessons.map(&:lessons_vocabularies).flatten
objectives = script.lessons.map(&:objectives).flatten

seed_context = SeedContext.new(
Expand All @@ -57,8 +55,6 @@ def self.serialize_seeding_json(script)
levels: my_levels,
resources: resources,
lessons_resources: lessons_resources,
vocabularies: vocabularies,
lessons_vocabularies: lessons_vocabularies,
objectives: objectives
)
scope = {seed_context: seed_context}
Expand All @@ -73,8 +69,6 @@ def self.serialize_seeding_json(script)
levels_script_levels: script.levels_script_levels.map {|lsl| ScriptSeed::LevelsScriptLevelSerializer.new(lsl, scope: scope).as_json},
resources: resources.map {|r| ScriptSeed::ResourceSerializer.new(r, scope: scope).as_json},
lessons_resources: lessons_resources.map {|lr| ScriptSeed::LessonsResourceSerializer.new(lr, scope: scope).as_json},
vocabularies: vocabularies.map {|v| ScriptSeed::VocabularySerializer.new(v, scope: scope).as_json},
lessons_vocabularies: lessons_vocabularies.map {|lv| ScriptSeed::LessonsVocabularySerializer.new(lv, scope: scope).as_json},
objectives: objectives.map {|o| ScriptSeed::ObjectiveSerializer.new(o, scope: scope).as_json}
}
JSON.pretty_generate(data)
Expand Down Expand Up @@ -144,8 +138,6 @@ def self.seed_from_json(json_string)
levels_script_levels_data = data['levels_script_levels']
resources_data = data['resources']
lessons_resources_data = data['lessons_resources']
vocabularies_data = data['vocabularies']
lessons_vocabularies_data = data['lessons_vocabularies']
objectives_data = data['objectives']
seed_context = SeedContext.new

Expand All @@ -157,9 +149,9 @@ def self.seed_from_json(json_string)

seed_context.script = import_script(script_data)

# Course version must be set before resources and vocabulary are imported. If the
# Course version must be set before resources are imported. If the
# script is in a unit group, we must wait and let the next seed step set
# the course version on the unit group before resources and vocabulary can be imported.
# the course version on the unit group before resources can be imported.
if seed_context.script.is_course
CourseOffering.add_course_offering(seed_context.script)
end
Expand All @@ -183,8 +175,6 @@ def self.seed_from_json(json_string)

seed_context.resources = import_resources(resources_data, seed_context)
seed_context.lessons_resources = import_lessons_resources(lessons_resources_data, seed_context)
seed_context.vocabularies = import_vocabularies(vocabularies_data, seed_context)
seed_context.lessons_vocabularies = import_lessons_vocabularies(lessons_vocabularies_data, seed_context)
seed_context.objectives = import_objectives(objectives_data, seed_context)

seed_context.script
Expand Down Expand Up @@ -391,70 +381,6 @@ def self.import_lessons_resources(lessons_resources_data, seed_context)
LessonsResource.joins(:lesson).where('stages.script_id' => seed_context.script.id)
end

def self.import_vocabularies(vocabularies_data, seed_context)
course_version_id = seed_context.script.get_course_version&.id

return [] if vocabularies_data.blank?

unless course_version_id
# We can't import any vocabulary without a course version, because
# course_version_id is required for vocabulary. Don't raise, because we
# may be in the scenario where this script does belong to a unit group,
# but that association is not present in the database yet because the
# seed process has not yet run on this machine since that relationship
# was added. In this scenario, the relationship to the unit group and
# its course version will be established in a later seed step. Then,
# this method will be able to import vocabulary the next time the
# seed process runs.
if vocabularies_data.count > 0
puts "WARNING: unable to import vocabulary into script #{seed_context.script.name} "\
"because course version is missing. This is only to be expected if "\
"the script is being seeded for the first time."
end
return []
end

vocabularies_to_import = vocabularies_data.map do |vocabulary_data|
vocabulary_attrs = vocabulary_data.except('seeding_key')
vocabulary_attrs['course_version_id'] = course_version_id
Vocabulary.new(vocabulary_attrs)
end

# Vocabulary are owned by the course version. Therefore, do not delete
# any vocabulary which no longer appear in the serialized data.
Vocabulary.import! vocabularies_to_import, on_duplicate_key_update: get_columns(Vocabulary)
vocabulary_keys = vocabularies_to_import.map(&:key)
Vocabulary.where(course_version_id: course_version_id, key: vocabulary_keys)
end

def self.import_lessons_vocabularies(lessons_vocabularies_data, seed_context)
return [] unless seed_context.script.get_course_version
return [] if lessons_vocabularies_data.blank?

lessons_vocabularies_to_import = lessons_vocabularies_data.map do |lv_data|
lesson_id = seed_context.lessons.select {|l| l.key == lv_data['seeding_key']['lesson.key']}.first&.id
raise 'No lesson found' if lesson_id.nil?

vocabulary_id = seed_context.vocabularies.select {|v| v.key == lv_data['seeding_key']['vocabulary.key']}.first&.id
raise 'No vocabulary found' if vocabulary_id.nil?

LessonsVocabulary.new(
lesson_id: lesson_id,
vocabulary_id: vocabulary_id
)
end

# destroy_outdated_objects won't work on LessonsVocabulary objects because
# they do not have an id field. Work around this by inefficiently deleting
# all LessonsVocabularies using 1 query per lesson, and then re-importing all
# LessonsVocabularies in a single query. It may be possible to eliminate
# these extra queries by adding an id column to the LessonsVocabularies model.
seed_context.lessons.each {|l| l.vocabularies = []}

LessonsVocabulary.import! lessons_vocabularies_to_import, on_duplicate_key_update: get_columns(LessonsVocabulary)
LessonsVocabulary.joins(:lesson).where('stages.script_id' => seed_context.script.id)
end

def self.import_objectives(objectives_data, seed_context)
objectives_to_import = objectives_data.map do |objective_data|
lesson_id = seed_context.lessons.select {|l| l.key == objective_data['seeding_key']['lesson.key']}.first&.id
Expand Down Expand Up @@ -607,22 +533,6 @@ def seeding_key
end
end

class VocabularySerializer < ActiveModel::Serializer
attributes :key, :word, :definition, :seeding_key

def seeding_key
object.seeding_key(@scope[:seed_context])
end
end

class LessonsVocabularySerializer < ActiveModel::Serializer
attributes :seeding_key

def seeding_key
object.seeding_key(@scope[:seed_context])
end
end

class ObjectiveSerializer < ActiveModel::Serializer
attributes :key, :properties, :seeding_key

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,7 @@
"lessons_resources": [

],
"vocabularies": [

],
"lessons_vocabularies": [

],
"objectives": [
"objectives": [

]
}
60 changes: 0 additions & 60 deletions dashboard/test/fixtures/test-serialize-seeding-json.script_json
Original file line number Diff line number Diff line change
Expand Up @@ -830,66 +830,6 @@
}
}
],
"vocabularies": [
{
"key": "test-serialize-seeding-json-lg-1-l-1-vocab-1",
"word": "word",
"definition": "definition",
"seeding_key": {
"vocabulary.key": "test-serialize-seeding-json-lg-1-l-1-vocab-1"
}
},
{
"key": "test-serialize-seeding-json-lg-1-l-1-vocab-2",
"word": "word",
"definition": "definition",
"seeding_key": {
"vocabulary.key": "test-serialize-seeding-json-lg-1-l-1-vocab-2"
}
},
{
"key": "test-serialize-seeding-json-lg-1-l-2-vocab-1",
"word": "word",
"definition": "definition",
"seeding_key": {
"vocabulary.key": "test-serialize-seeding-json-lg-1-l-2-vocab-1"
}
},
{
"key": "test-serialize-seeding-json-lg-1-l-2-vocab-2",
"word": "word",
"definition": "definition",
"seeding_key": {
"vocabulary.key": "test-serialize-seeding-json-lg-1-l-2-vocab-2"
}
}
],
"lessons_vocabularies": [
{
"seeding_key": {
"lesson.key": "test-serialize-seeding-json-lg-1-l-1",
"vocabulary.key": "test-serialize-seeding-json-lg-1-l-1-vocab-1"
}
},
{
"seeding_key": {
"lesson.key": "test-serialize-seeding-json-lg-1-l-1",
"vocabulary.key": "test-serialize-seeding-json-lg-1-l-1-vocab-2"
}
},
{
"seeding_key": {
"lesson.key": "test-serialize-seeding-json-lg-1-l-2",
"vocabulary.key": "test-serialize-seeding-json-lg-1-l-2-vocab-1"
}
},
{
"seeding_key": {
"lesson.key": "test-serialize-seeding-json-lg-1-l-2",
"vocabulary.key": "test-serialize-seeding-json-lg-1-l-2-vocab-2"
}
}
],
"objectives": [
{
"key": "test-serialize-seeding-json-lg-1-l-1-objective-1",
Expand Down