Skip to content

Commit

Permalink
Modified registry to look up models by convention
Browse files Browse the repository at this point in the history
  • Loading branch information
Evan Light committed Mar 15, 2013
1 parent 8414f95 commit 160823b
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 8 deletions.
30 changes: 22 additions & 8 deletions lib/edr/registry.rb
Expand Up @@ -3,21 +3,37 @@
module Edr
class Registry
def self.define(&block)
@@instance = self.new(&block)
@instance = self.new(&block)
end

def self.data_class_for(model_class)
@@instance.data_class_for(model_class)
@instance.data_class_for(model_class)
end

def self.model_class_for(data_class)
@@instance.model_class_for(data_class)
@instance.model_class_for(data_class)
end

def self.map_models_to_mappers
define unless @instance

ObjectSpace.each_object do |o|

This comment has been minimized.

Copy link
@ruprict

ruprict May 6, 2013

FWIW, ObjectSpace is disabled in JRuby by default, so this won't work unless you enable it, which is (from what I can tell) a pretty big performance hit. https://github.com/jruby/jruby/wiki/PerformanceTuning#dont-enable-objectspace

This comment has been minimized.

Copy link
@elight

elight May 25, 2013

Owner

Makes sense. But then you still need a way to locate arbitrary subclasses of AR::Base conforming to the naming conventions. JRuby may have it's own way to do this?

next unless o.is_a?(Class) &&
o.ancestors.include?(ActiveRecord::Base) &&
o.to_s =~ /Data$/
model_name = o.to_s.sub(/Data$/, "")

next unless Object.const_defined?(model_name)

model_class = Object.const_get(model_name)
@instance.map(model_class, o)
end
end

def initialize(&block)
@data_to_model_map = {}
@model_to_data_map = {}
self.instance_eval &block
#self.instance_eval &block

This comment has been minimized.

Copy link
@ruprict

ruprict Mar 21, 2013

So, how do you propose to do this in Rails? You can't just call map_model_to_mappers in an initializer without manually loading all the models first. If you take out the eval of the block, I have to do something like:

edr = Edr::Registry.define
edr.map Model, ModelData
... keep going for each class ...

in development which is kinda gross. I am fully prepared to not understand if there is a better way...

This comment has been minimized.

Copy link
@elight

elight via email Mar 21, 2013

Owner

This comment has been minimized.

Copy link
@elight

elight via email Mar 21, 2013

Owner

This comment has been minimized.

Copy link
@ruprict

ruprict via email Mar 21, 2013

This comment has been minimized.

Copy link
@elight

elight via email Mar 21, 2013

Owner

This comment has been minimized.

Copy link
@ruprict

ruprict via email Mar 21, 2013

This comment has been minimized.

Copy link
@elight

elight via email Mar 21, 2013

Owner

This comment has been minimized.

Copy link
@elight

elight via email Mar 21, 2013

Owner

This comment has been minimized.

Copy link
@elight

elight via email Mar 21, 2013

Owner
end

# the mapping is done by the class names, to avoid
Expand All @@ -31,14 +47,12 @@ def data_class_for model_class
data_class = @model_to_data_map[model_class.to_s]
return OpenStruct unless data_class

data_class.constantize
Object.const_get(data_class)
end

def model_class_for data_class
model_class = @data_to_model_map[data_class.to_s]
raise "No model class for #{data_class.to_s}" unless model_class

model_class.constantize
model_class ? model_class.constantize : nil
end

private
Expand Down
25 changes: 25 additions & 0 deletions spec/edr/registry_spec.rb
@@ -0,0 +1,25 @@
require 'spec_helper'
require_relative '../../lib/edr/registry'

describe Edr::Registry do
class HasAModelData < ActiveRecord::Base; end
class HasAModel; end

class DoesntHaveAModelData < ActiveRecord::Base; end

context "defining domain model to active record mappings" do
subject { Edr::Registry }

before do
subject.map_models_to_mappers
end

it "maps every AR::Base with a class name ending in 'Data' to a domain model class with the same name less 'Data'" do
expect(subject.model_class_for(HasAModelData)).to eq(HasAModel)
end

it "does not map an AR::Base ending in 'Data' to a domain model if none exist with the same name less 'Data'" do
expect(subject.model_class_for(DoesntHaveAModelData)).to be_nil
end
end
end

0 comments on commit 160823b

Please sign in to comment.