diff --git a/lib/import/base_resource.rb b/lib/import/base_resource.rb new file mode 100644 index 000000000..ebb8d6283 --- /dev/null +++ b/lib/import/base_resource.rb @@ -0,0 +1,84 @@ +module Import + class BaseResource + include Import::Helper + + def initialize(resource) + import(resource) + end + + def import_class + raise "#{self.class.name} has no implmentation of the needed 'import_class' method" + end + + private + + def import(resource) + create_or_update(map(resource)) + end + + def create_or_update(resource) + return if updated?(resource) + create(resource) + end + + def updated?(resource) + @resource = lookup_existing(resource) + return false if !@resource + @resource.update_attributes(resource) + post_update( + instance: @resource, + attributes: resource + ) + true + end + + def lookup_existing(resource) + import_class.find_by(name: resource[:name]) + end + + def create(resource) + @resource = import_class.new(resource) + @resource.save + post_create( + instance: @resource, + attributes: resource + ) + end + + def defaults(_resource) + { + created_by_id: 1, + updated_by_id: 1, + } + end + + def map(resource) + mapped = from_mapping(resource) + attributes = defaults(resource).merge(mapped) + attributes.deep_symbolize_keys + end + + def from_mapping(resource) + return resource if !mapping + + ExternalSync.map( + mapping: mapping, + source: resource + ) + end + + def mapping + Setting.get(mapping_config) + end + + def mapping_config + self.class.name.to_s.sub('Import::', '').gsub('::', '_').underscore + '_mapping' + end + + def post_create(_args) + end + + def post_update(_args) + end + end +end diff --git a/lib/import/model_resource.rb b/lib/import/model_resource.rb new file mode 100644 index 000000000..3c3c23398 --- /dev/null +++ b/lib/import/model_resource.rb @@ -0,0 +1,18 @@ +module Import + class ModelResource < Import::BaseResource + + def import_class + model_name.constantize + end + + def model_name + @model_name ||= self.class.name.split('::').last + end + + private + + def post_create(_args) + reset_primary_key_sequence(model_name.underscore.pluralize) + end + end +end diff --git a/spec/import/base_resource_spec.rb b/spec/import/base_resource_spec.rb new file mode 100644 index 000000000..13a79d4aa --- /dev/null +++ b/spec/import/base_resource_spec.rb @@ -0,0 +1,10 @@ +require 'rails_helper' + +RSpec.describe Import::BaseResource do + + it "needs an implementation of the 'import_class' method" do + expect { + described_class.new(attributes_for(:group)) + }.to raise_error(RuntimeError) + end +end diff --git a/spec/import/model_resource_spec.rb b/spec/import/model_resource_spec.rb new file mode 100644 index 000000000..005ba864c --- /dev/null +++ b/spec/import/model_resource_spec.rb @@ -0,0 +1,35 @@ +require 'rails_helper' + +RSpec.describe Import::ModelResource do + + before do + module Import + module Test + class Group < Import::ModelResource + end + end + end + end + + it 'creates model Objects by class name' do + + group_data = attributes_for(:group) + + expect { + Import::Test::Group.new(group_data) + }.to change { Group.count }.by(1) + end + + it 'updates model Objects by class name' do + + group = create(:group) + + update_attributes = group.serializable_hash + update_attributes[:note] = 'Updated' + + expect { + Import::Test::Group.new(update_attributes) + group.reload + }.to change { group.note } + end +end