Last active
August 26, 2016 21:46
-
-
Save mreq/2846000864a49c9b936dff77f224014e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'open-uri' | |
class YamlFixtureLoader | |
def load!(paths) | |
paths.each do |path| | |
load_path!(path) | |
end | |
end | |
private | |
def load_path!(path) | |
yaml_data = YAML::load_file(path) | |
CollectionLoader.new(yaml_data).load! | |
end | |
class CollectionLoader | |
def initialize(yaml_data) | |
@collection = yaml_data.first.second | |
@model = yaml_data.keys.first.constantize | |
end | |
def load! | |
@collection.each do |item| | |
ModelLoader.new(item, @model).load! | |
end | |
end | |
end | |
class ModelLoader | |
def initialize(data, model, build_from = nil) | |
@data = data | |
@model = model | |
if build_from | |
@instance = build_from.build | |
else | |
@instance = @model.new | |
end | |
end | |
def load!(should_save = true) | |
load_attributes! | |
load_translations! | |
load_attachment! | |
load_relations! | |
@instance.save! if should_save | |
@instance | |
end | |
private | |
def load_attributes! | |
columns = @model.column_names & @data.keys - ['attachment'] | |
columns.each do |column| | |
@instance[column] = @data[column] | |
end | |
end | |
def load_translations! | |
return unless @data.keys.include? 'translations' | |
valid_keys = @model.translation_class.column_names | |
@data['translations'].each do |translation| | |
translation.select! { |key, _| valid_keys.include? key } | |
@instance.translations << @model.translation_class.new(translation) | |
end | |
end | |
def load_attachment! | |
return unless @data.keys.include? 'attachment' | |
path = @data['attachment'] | |
if path =~ /http/ | |
attachment = open(path).read | |
else | |
attachment = File.new(Rails.root.join(path)) | |
end | |
@instance.attachment = attachment | |
end | |
def load_relations! | |
@model.reflect_on_all_associations.each do |reflection| | |
case reflection.class.to_s | |
when 'ActiveRecord::Reflection::HasManyReflection' | |
load_relations_has_many!(reflection) | |
when 'ActiveRecord::Reflection::BelongsToReflection' | |
load_relations_belongs_to!(reflection) | |
when 'ActiveRecord::Reflection::HasOneReflection' | |
load_relations_has_one!(reflection) | |
end | |
end | |
end | |
def load_relations_has_many!(reflection) | |
column = reflection.plural_name | |
return unless @data.keys.include? column | |
@data[column].each do |related_item| | |
model = ModelLoader.new(related_item, | |
reflection.class_name.constantize, | |
eval("@instance.#{column}")).load!(false) | |
eval("@instance.#{column} << model") | |
end | |
end | |
def load_relations_belongs_to!(reflection) | |
column = reflection.name.to_s | |
return unless @data.keys.include? column | |
eval("@instance.#{column} = reflection.class_name.constantize.find_by(@data[column])") | |
end | |
def load_relations_has_one!(reflection) | |
column = reflection.name.to_s | |
return unless @data.keys.include? column | |
eval("@instance.#{column} = ModelLoader.new(@data[column], reflection.class_name.constantize).load!(false)") | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment