Added generic resource import logic to provide base classes containing the generic core logic for importing single resources. Direct import from remote objects to local models is possible by using Import::ModelResource.

This commit is contained in:
Thorsten Eckel 2017-03-08 16:02:56 +01:00
parent 32fe702e56
commit fafe7f3421
4 changed files with 147 additions and 0 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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