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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/dm-reflection/reflection.rb', line 10

def self.reflect(repository, namespace = Object, overwrite = false)
  adapter = DataMapper.repository(repository).adapter
  separator = adapter.separator
  models  = Hash.new

  adapter.get_storage_names.each do |storage_name|
    namespace_parts = storage_name.split(separator).map do |part|
      ActiveSupport::Inflector.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 "        storage_names[\#{repository.inspect}]='\#{storage_name}'\n      RUBY\n      unless repository == DataMapper::Repository.default_name\n        class_eval <<-RUBY, __FILE__, __LINE__\n          def self.default_repository_name\n            \#{repository.inspect}\n          end\n        RUBY\n      end\n    end\n    \n    full_name = namespace_parts.length > 0 ? [namespace_parts, model_name].join('::') : model_name\n    models[full_name] = namespace.const_set(model_name, anonymous_model)\n  end\n\n  join_models = Array.new\n  \n  models.each do |model_name, model|\n    adapter.get_properties(model.storage_name).each do |attribute|\n      if attribute[:type] == :many_to_many\n        attribute.delete(:type)\n        attribute.delete(:name)\n        relationship = attribute.delete(:relationship)\n        parent = models[relationship.delete(:parent)]\n        child = models[relationship.delete(:child)]\n        cardinality = relationship.delete(:cardinality)\n        parent.has(cardinality, relationship[:child_name].to_sym, attribute.merge({:through => DataMapper::Resource, :model => child}))\n        child.has(cardinality, relationship[:parent_name].to_sym, attribute.merge({:through => DataMapper::Resource, :model => parent}))\n        join_models << model_name\n      elsif attribute[:type] == :has_n\n        attribute.delete(:type)\n        model.has(attribute.delete(:cardinality), attribute.delete(:name).to_sym, attribute)\n      elsif attribute[:type] == :belongs_to\n        attribute.delete(:type)\n        other_side = attribute.delete(:other_side)\n        name = attribute.delete(:name)\n#            puts \"\#{model.name}.belongs_to(\#{name}, \#{attribute.inspect})\"\n        model.belongs_to(name.to_sym, attribute.dup)\n        unless other_side.nil?\n          other_name = other_side.delete(:name)\n          cardinality = other_side.delete(:cardinality)\n          other_side[:model] = ActiveSupport::Inflector.singularize(model)\n#              puts \"\#{models[attribute[:model]]}.has(\#{cardinality}, \#{other_name}, \#{other_side.inspect})\"\n          models[attribute[:model]].has(cardinality, other_name.to_sym, other_side)\n        end\n      else\n        attribute.delete_if { |k,v| v.nil? }\n        model.property(attribute.delete(:name).to_sym, attribute.delete(:type), attribute)\n      end\n    end\n  end\n      \n  join_models.each do |model|\n    models.delete(model)\n    DataMapper::Model.descendants.delete(model)\n  end\n\n  models.values\nend\n", __FILE__, __LINE__