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:
parent
32fe702e56
commit
fafe7f3421
4 changed files with 147 additions and 0 deletions
84
lib/import/base_resource.rb
Normal file
84
lib/import/base_resource.rb
Normal 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
|
18
lib/import/model_resource.rb
Normal file
18
lib/import/model_resource.rb
Normal 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
|
10
spec/import/base_resource_spec.rb
Normal file
10
spec/import/base_resource_spec.rb
Normal 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
|
35
spec/import/model_resource_spec.rb
Normal file
35
spec/import/model_resource_spec.rb
Normal 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
|
Loading…
Reference in a new issue