Module: DataMapper::Reflection

Defined in:
lib/dm-reflection/reflection.rb,
lib/dm-reflection/adapters/mysql.rb,
lib/dm-reflection/adapters/sqlite3.rb,
lib/dm-reflection/adapters/postgres.rb,
lib/dm-reflection/adapters/persevere.rb,
lib/dm-reflection/builders/source_builder.rb

Defined Under Namespace

Modules: Builders, MysqlAdapter, PersevereAdapter, PostgresAdapter, Sqlite3Adapter

Class Method Summary collapse

Class Method Details

.reflect(repository, namespace = Object, overwrite = false) ⇒ DataMapper::Model Array

Main reflection method reflects models out of a repository.

Parameters:

  • repository (Slug)

    is the key to the repository that will be reflected.

  • namespace (Constant) (defaults to: Object)

    is the namespace into which the reflected models will be added

  • overwrite (Boolean) (defaults to: false)

    indicates the reflected models should replace existing models or not.

Returns:

  • (DataMapper::Model Array)

    the reflected models.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/dm-reflection/reflection.rb', line 10

def self.reflect(repository, namespace = Object, overwrite = false)
  adapter = DataMapper.repository(repository).adapter

  models  = Hash.new

  adapter.get_storage_names.each do |storage_name|
    namespace_parts = storage_name.split('__').map do |part|
      Extlib::Inflection.classify(part)
    end

    model_name = namespace_parts.pop

    namespace = if namespace_parts.any?
      Object.make_module(namespace_parts.join('::'))
    else
      Object
    end

    next if namespace.const_defined?(model_name) && !overwrite

    anonymous_model = DataMapper::Model.new do
      class_eval <<-RUBY, __FILE__, __LINE__
        storage_names[#{repository.inspect}]='#{storage_name}'
      RUBY
      unless repository == DataMapper::Repository.default_name
        class_eval <<-RUBY, __FILE__, __LINE__
          def self.default_repository_name
            #{repository.inspect}
          end
        RUBY
      end
    end

    models[model_name] = namespace.const_set(model_name, anonymous_model)
  end

  models.values.each do |model|
    adapter.get_properties(model.storage_name).each do |attribute|
      if attribute[:type] == DataMapper::Associations::Relationship
        parent = models[attribute[:relationship][:parent]]
        child = models[attribute[:relationship][:child]]
        child.belongs_to(parent.name.downcase.to_sym)
        if attribute[:relationship][:bidirectional]
          parent.has(attribute[:relationship][:cardinality], child.name.pluralize.downcase.to_sym)
        end
      else
        attribute.delete_if { |k,v| v.nil? }
        model.property(attribute.delete(:name).to_sym, attribute.delete(:type), attribute)
      end
    end
  end
    
  models.to_a
end