Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions lib/replicate/loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,17 @@ def read(io)
# Returns the new object instance.
def load(type, id, attributes)
model_class = constantize(type)

return if model_class.nil?

translate_ids type, id, attributes
begin
new_id, instance = model_class.load_replicant(type, id, attributes)
rescue => boom
warn "error: loading #{type} #{id} #{boom.class} #{boom}"

return if ignore_missing?

raise
end
register_id instance, type, id, new_id
Expand Down Expand Up @@ -123,6 +129,15 @@ def register_id(object, type, remote_id, local_id)
end
end

# Silently ignore missing replication types instead of raising an
# uninitialized constant error. Allows for replication between mismatched
# object graphs.
def ignore_missing!
@ignore = true
end

def ignore_missing? ; @ignore ; end

# Turn a string into an object by traversing constants. Identical to
# ActiveSupport's String#constantize implementation.
if Module.method(:const_get).arity == 1
Expand All @@ -132,7 +147,15 @@ def constantize(string)
if namespace.const_defined?(name)
namespace.const_get(name)
else
namespace.const_missing(name)
begin
namespace.const_missing(name)
rescue NameError => e
if ignore_missing?
warn "ignoring missing type #{name}"
else
raise e
end
end
end
end
end
Expand All @@ -143,7 +166,15 @@ def constantize(string)
if namespace.const_defined?(name, false)
namespace.const_get(name)
else
namespace.const_missing(name)
begin
namespace.const_missing(name)
rescue NameError => e
if ignore_missing?
warn "ignoring missing type #{name}"
else
raise e
end
end
end
end
end
Expand Down
36 changes: 36 additions & 0 deletions test/loader_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,40 @@ def test_translating_multiple_id_attributes
assert_equal 11, objects.size
assert_equal 10, objects.last.related.size
end

def test_ignoring_a_missing_type
dumper = Replicate::Dumper.new

objects = []
dumper.listen { |type, id, attrs, obj| objects << [type, id, attrs, obj] }

with_ghost_class do |klass|
dumper.dump(klass.new)
end

begin
objects.each { |type, id, attrs, obj| @loader.feed type, id, attrs }

assert_fail "NameError unexpectedly ignored"
rescue NameError
end

@loader.ignore_missing!

objects.each { |type, id, attrs, obj| @loader.feed type, id, attrs }
end

def with_ghost_class
eval <<-RUBY
class ::Ghost
def dump_replicant(dumper)
dumper.write self.class, 3, {}, self
end
end
RUBY

yield Ghost
ensure
Object.send(:remove_const, :Ghost)
end
end