Class: Tables

Inherits:
Object
  • Object
show all
Defined in:
lib/dbmodel.rb

Overview

A class to handle parsing of table information from a datamodel XML file. Since relationships are defined by table IDs, a hash is constructed using table IDs.

Instance Method Summary collapse

Constructor Details

#initializeTables

Returns a new instance of Tables.



36
37
38
# File 'lib/dbmodel.rb', line 36

def initialize
  @table_hash = Hash.new
end

Instance Method Details

#add_relationship(r) ⇒ Object

Adds a relationship to the hash, where the relationship has source and destination table IDs definied by attributes SrcTable and DstTable. The RelationName attribute should be Rails-valid code. To-do: this could be made more robust where we trace the relationships through join tables and don’t require any model names in the relationship name.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/dbmodel.rb', line 55

def add_relationship(r)
  src_table_id = r.attributes['SrcTable']
  src_table_name = @table_hash[src_table_id]['name']
  dest_table_id = r.attributes['DestTable']
  dest_table_name = @table_hash[dest_table_id]['name']
  
  relationship = r.attributes['RelationName']
  if relationship =~ /\s*habtm\s*:(\w+)/
    relationship = "  has_and_belongs_to_many :#{$1}"
  else
    # If we are inserting the other side of a relationship (non-habtm),
    # we need to mirror the relationship.
    # NOTE: in the DB model, links should be labeled 'has_one' or 'has_many'
    #       not 'belongs_to' since that label is ambiguous 1:1 or 1:n
    if relationship =~ /has_one/ or relationship =~ /has_many/
      @table_hash[dest_table_id]['relationships'] << '  belongs_to :' + src_table_name
    else relationship !~ /has_and_belongs_to_many/
      puts "error: relationships must be labeled 'has_one :x', 'has_many :x', 'habtm :x' or 'has_and_belongs_to_many :x'"
      return
    end
    relationship = '  ' + relationship
  end
  @table_hash[src_table_id]['relationships'] << relationship
end

#add_table(t) ⇒ Object

Adds a table to the hash, where the table is a REXML::Element with ID, Tablename, and Comments attributes



42
43
44
45
46
47
48
# File 'lib/dbmodel.rb', line 42

def add_table(t)
  @table_hash[t.attributes['ID']] = {
    'name' => t.attributes['Tablename'],
    'comments' => t.attributes['Comments'],
    'relationships' => []
  }
end

#update_files(xmlfile) ⇒ Object

Updates the Rails app files to reflect what’s in the table hash. The location of the Rails app is gleaned from xmlfile, which is assumed to be in /db. If a model file doesn’t exist, a generate model or generate scaffold is called, depending on the presence of a [SCAFFOLD] tag in the table comments. Existing files are checked to make sure the relationship is defined. To-do: old relationships aren’t removed



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/dbmodel.rb', line 86

def update_files(xmlfile)
  @table_hash.each do |table_id, table|
    if not table['relationships'].empty?
      add_comments = false
      # If there's no model file, create one via generate scaffold script
      modelfile = File.dirname(xmlfile) + '\..\app\models\\' + table['name'].singularize + '.rb'
      if File.exist?(modelfile)
        puts "Model file (#{table['name'].singularize}) already exists. Skipping generation." if not $silent
      elsif table['comments'] =~ /\[\s*SCAFFOLD\s*(\s.*)*\s*\]/
        cmdline = ['scaffold', table['name'].singularize]
        if not $1.nil?
          $1.split(' ').collect { |arg| cmdline << arg }
        end
        cmdline << '-f'
        puts "Calling generator: #{cmdline.join(' ')}" if not $silent
        Rails::Generator::Scripts::Generate.new.run(cmdline) if not $dryrun
        add_comments = true
      elsif
        cmdline = ['model', table['name'].singularize, '-f']
        puts "Generating model for #{table['name'].singularize}" if not $silent
        Rails::Generator::Scripts::Generate.new.run(cmdline) if not $dryrun
        add_comments = true
      end

      update_file(modelfile, table_id, add_comments) if not $dryrun
    end
  end
end