Skip to content

Commit

Permalink
Merge pull request #38524 from code-dot-org/revert-38469-seed-seriali…
Browse files Browse the repository at this point in the history
…ze-vocab

Revert "Seed and serialize vocab"
  • Loading branch information
bethanyaconnor committed Jan 12, 2021
2 parents 0369ed9 + 3b90478 commit af958f8
Show file tree
Hide file tree
Showing 9 changed files with 9 additions and 283 deletions.
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

0 comments on commit af958f8

Please sign in to comment.