dr_nic_magic_models 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/base.rb CHANGED
@@ -3,14 +3,10 @@
3
3
  module ActiveRecord
4
4
  class Base
5
5
  class << self
6
-
7
6
  public
8
-
9
7
  def get_unique_index_columns
10
8
  self.connection.indexes(self.table_name, "#{self.name} Indexes").select { |index| index.unique && index.columns.size == 1 }.map{ |index| index.columns.first }
11
- end
9
+ end
12
10
  end
13
-
14
-
15
11
  end
16
12
  end
@@ -14,15 +14,18 @@ module DrNicMagicModels
14
14
  Logger = RAILS_DEFAULT_LOGGER rescue Logger.new(STDERR)
15
15
  end
16
16
 
17
+ require 'dr_nic_magic_models/magic_model'
17
18
  require 'dr_nic_magic_models/schema'
18
19
  require 'dr_nic_magic_models/validations'
20
+ require 'dr_nic_magic_models/inflector'
19
21
  require 'base'
22
+ require 'module'
20
23
  require 'rails' rescue nil
21
24
  require 'connection_adapters/abstract_adapter'
22
25
  require 'connection_adapters/mysql_adapter'
23
26
  require 'connection_adapters/postgresql_adapter'
24
27
 
25
28
  # load the schema
26
- DrNicMagicModels::Schema.load_schema
29
+ # TODO - add this to README - DrNicMagicModels::Schema.load_schema(true)
27
30
 
28
31
 
@@ -0,0 +1,14 @@
1
+ module DrNicMagicModels
2
+ class Inflector
3
+ def table_names ; DrNicMagicModels::Schema.table_names; end
4
+ def tables ; DrNicMagicModels::Schema.tables; end
5
+ def models ; DrNicMagicModels::Schema.model; end
6
+
7
+ def class_name(table_name)
8
+ ActiveRecord::Base.class_name(table_name)
9
+ end
10
+
11
+ def post_class_creation(klass)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,125 @@
1
+ # Mixed into a class that is dynamically created, unless
2
+ # the class was created by the Schema.load_schema process
3
+ # which builds the whole class, thus no magicalness is
4
+ # needed
5
+ module DrNicMagicModels::MagicModel
6
+ def self.append_features(base)
7
+ super
8
+ base.send(:include, InstanceMethods)
9
+ class << base
10
+ # Returns the AssociationReflection object for the named +aggregation+ (use the symbol). Example:
11
+ # Account.reflect_on_association(:owner) # returns the owner AssociationReflection
12
+ # Invoice.reflect_on_association(:line_items).macro # returns :has_many
13
+ def reflect_on_association(association)
14
+ unless reflections[association]
15
+ # See if an assocation can be generated
16
+ self.new.send(association) rescue nil
17
+ end
18
+ reflections[association].is_a?(ActiveRecord::Reflection::AssociationReflection) ? reflections[association] : nil
19
+ end
20
+ end
21
+ end
22
+
23
+ module InstanceMethods
24
+
25
+ def method_missing(method, *args, &block)
26
+ begin
27
+ super
28
+ rescue
29
+ if unknown_method? method
30
+ result = find_belongs_to method, *args, &block
31
+ result = find_has_some method, *args, &block if not result
32
+ result = find_has_some_indirect method, *args, &block if not result
33
+ return result if result
34
+ end
35
+ add_known_unknown method
36
+ raise
37
+ end
38
+ end
39
+
40
+ def add_known_unknown(method)
41
+ @known_unknowns ||= {}
42
+ @known_unknowns[method] = true
43
+ end
44
+
45
+ def unknown_method?(method)
46
+ @known_unknowns.nil? or @known_unknowns.include? method
47
+ end
48
+
49
+ def find_belongs_to(method, *args, &block)
50
+ fkc =
51
+ begin
52
+ self.class.connection.foreign_key_constraints(self.class.table_name, method)
53
+ rescue NotImplementedError
54
+ nil
55
+ end
56
+ if not fkc.nil? and fkc.length > 0
57
+ foreign_key = fkc.first.foreign_key
58
+ options = {:dependent => :destroy, :foreign_key => fkc.first.foreign_key, :class_name => self.class.class_name(fkc.first.reference_table)}
59
+ else
60
+ foreign_key = self.class.columns.select {|column| column.name == method.to_s.foreign_key}.first
61
+ end
62
+ options ||= {}
63
+ return add_belongs_to(method, options, *args, &block) if foreign_key
64
+ end
65
+
66
+ def add_belongs_to(method, options, *args, &block)
67
+ self.class.send 'belongs_to', method, options rescue puts $!
68
+ self.send(method, *args, &block)
69
+ end
70
+
71
+ def find_has_some(method, *args, &block)
72
+ fkc = [method.to_s.pluralize, method.to_s.singularize].inject({}) do |pair, table_name|
73
+ fkc = begin
74
+ self.class.connection.foreign_key_constraints(table_name)
75
+ rescue NotImplementedError
76
+ nil
77
+ end
78
+ pair[table_name] = fkc if not fkc.blank?
79
+ pair
80
+ end
81
+ if not fkc.blank?
82
+ # assumes there is only one table found - that schema doesn't have a singular and plural table of same name
83
+ foreign_key = fkc.values.first.find {|fk| fk.reference_table == self.class.table_name}
84
+ if foreign_key
85
+ foreign_key = foreign_key.foreign_key
86
+ table_name = fkc.keys.first
87
+ klass = Module.const_get table_name.singularize.camelize rescue nil
88
+ options = {:foreign_key => foreign_key, :class_name => klass.name}
89
+ end
90
+ end
91
+ unless foreign_key
92
+ klass = Module.const_get method.to_s.downcase.singularize.camelize rescue nil
93
+ foreign_key = klass.columns.select {|column| column.name == self.class.name.foreign_key}.first if klass
94
+ end
95
+ options ||= {}
96
+ return add_has_some(method, options, *args, &block) if foreign_key
97
+ end
98
+
99
+ def add_has_some(method, options, *args, &block)
100
+ _method = method.to_s
101
+ association = _method.singularize == _method ? 'has_one' : 'has_many'
102
+ self.class.send association, method, options rescue puts $!
103
+ self.send(method, *args, &block)
104
+ end
105
+
106
+ def find_has_some_indirect(method, *args, &block)
107
+ klass = Module.const_get method.to_s.downcase.singularize.camelize rescue return
108
+ join_table = nil
109
+ self.connection.tables.each do |table|
110
+ unless [self.class.table_name, klass.table_name].include? table
111
+ columns = self.connection.columns(table).map(&:name)
112
+ join_table = table if columns.include?(self.class.to_s.foreign_key) and columns.include?(klass.to_s.foreign_key)
113
+ end
114
+ break if join_table
115
+ end
116
+ return add_has_some_through(join_table, method, *args, &block) if join_table
117
+ end
118
+
119
+ def add_has_some_through(join_table, method, *args, &block)
120
+ puts "#{self.class}.has_many #{method.inspect}, #{join_table.inspect}, #{args.inspect}"
121
+ self.class.send 'has_many', method, :through => join_table.to_sym
122
+ self.send(method, *args, &block)
123
+ end
124
+ end
125
+ end
@@ -1,227 +1,255 @@
1
1
  module DrNicMagicModels
2
-
2
+
3
+ # ONE Schema per namespace module
4
+ # Person, Company, etc share the Object namespace module, ie. ::Person, ::Company
5
+ # Blog::Post, Blog::Comment, share the Blog namespace module
3
6
  class Schema
4
- class << self
7
+ attr_reader :modul
5
8
 
6
- # all in lower case please
7
- ReservedTables = [:schema_info, :sessions]
8
- @@models = nil
9
+ def initialize(modul)
10
+ @modul = modul
11
+ @table_name_prefix = modul.instance_variable_get("@table_name_prefix") rescue ''
12
+ logger.info "Create Schema for #{@modul}, table_name_prefix '#{@table_name_prefix}'"
13
+ end
9
14
 
10
- def logger
11
- @@logger ||= DrNicMagicModels::Logger
12
- end
15
+ cattr_accessor :inflector
16
+ cattr_accessor :superklass
13
17
 
14
- def models
15
- load_schema if @@models.nil?
16
- @@models
17
- end
18
+ # Need to store models etc per-module, not in @ @models
19
+ def inflector
20
+ @inflector ||= Inflector.new
21
+ end
22
+
23
+ # all in lower case please
24
+ ReservedTables = [:schema_info, :sessions]
25
+ @models = nil
26
+
27
+ def logger
28
+ @logger ||= DrNicMagicModels::Logger
29
+ end
30
+
31
+ def models
32
+ load_schema if @models.nil?
33
+ @models
34
+ end
35
+
36
+ def tables
37
+ load_schema if @tables.nil?
38
+ @tables
39
+ end
40
+
41
+ def table_names
42
+ load_schema if @table_names.nil?
43
+ @table_names
44
+ end
45
+
46
+ def fks_on_table(table_name)
47
+ load_schema if @models.nil?
48
+ @fks_by_table[table_name.to_s] || []
49
+ end
50
+
51
+ # active record only support 2 column link tables, otherwise use a model table, has_many and through
52
+ def is_link_table?(table_name)
53
+ load_schema if @models.nil?
54
+ return @link_tables[table_name] if ! @link_tables[table_name].nil?
55
+ column_names = @conn.columns(table_name).map{|x| x.name }
56
+ @link_tables[table_name] = ! column_names.include?("id") && column_names.length == 2 && column_names.select { |x| x =~ /_id$/ } == column_names
57
+ return @link_tables[table_name]
58
+ end
59
+
60
+ def link_tables_for_class(klass)
61
+ load_schema if @models.nil?
62
+ end
63
+
64
+ def load_schema(preload = false)
65
+ return if !@models.nil?
18
66
 
19
- def fks_on_table(table_name)
20
- load_schema if @@models.nil?
21
- @@fks_by_table[table_name.to_s] || []
22
- end
67
+ @superklass ||= ActiveRecord::Base
68
+ raise "No database connection" if !(@conn = @superklass.connection)
23
69
 
24
- # active record only support 2 column link tables, otherwise use a model table, has_many and through
25
- def is_link_table?(table_name)
26
- load_schema if @@models.nil?
27
- return @@link_tables[table_name] if ! @@link_tables[table_name].nil?
28
- column_names = @conn.columns(table_name).map{|x| x.name }
29
- @@link_tables[table_name] = ! column_names.include?("id") && column_names.length == 2 && column_names.select { |x| x =~ /_id$/ } == column_names
30
- return @@link_tables[table_name]
31
- end
32
-
33
- def link_tables_for_class(klass)
34
- load_schema if @@models.nil?
35
- end
36
-
37
- def load_schema
70
+ @models = ModelHash.new
71
+ @tables = Hash.new
72
+ @fks_by_table = Hash.new
73
+ @link_tables = Hash.new
38
74
 
39
- return if ! @@models.nil?
75
+ @table_names = @conn.tables
76
+ @table_names = @table_names.grep(/^#{@table_name_prefix}/) if @table_name_prefix
77
+ @table_names = @table_names.sort
40
78
 
41
- raise "No database connection" if !(@conn = ActiveRecord::Base.connection)
42
-
43
- @@models = ModelHash.new
44
- @@tables = Hash.new
45
- @@fks_by_table = Hash.new
46
- @@link_tables = Hash.new
47
-
48
- tables = @conn.tables.sort
49
-
50
- # Work out which tables are in the model and which aren't
51
- tables.each do |table_name|
52
-
53
- # deal with reserved tables & link_tables && other stray id-less tables
54
- next if ReservedTables.include?(table_name.downcase.to_sym) || is_link_table?(table_name) || ! @conn.columns(table_name).map{ |x| x.name}.include?("id")
55
-
56
- # a model table then...
57
- model_class_name = ActiveRecord::Base.class_name(table_name)
58
-
59
- logger.debug "Got a model table: #{table_name} => class #{model_class_name}"
60
-
61
- @@models[model_class_name] = table_name
62
- @@tables[table_name] = model_class_name
63
-
64
- # create by MAGIC!
65
- begin
66
- klass = model_class_name.constantize
67
- rescue Exception => e
68
- # create our class!
69
- class_def = <<-end_eval
70
- class #{model_class_name} < ActiveRecord::Base
71
- set_table_name('#{table_name}')
72
- end
73
- end_eval
74
- eval(class_def, TOPLEVEL_BINDING)
75
- klass = model_class_name.constantize
76
- end
77
-
78
- # magic up some validation
79
- klass.send(:extend, DrNicMagicModels::Validations)
80
- klass.send(:generate_validations)
81
-
82
- end
83
-
84
- # Process FKs?
85
- if @conn.supports_fetch_foreign_keys?
79
+ logger.info "For #{modul} tables are #{@table_names.inspect}"
80
+
81
+ # Work out which tables are in the model and which aren't
82
+ @table_names.each do |table_name|
86
83
 
87
- tables.each do |table_name|
88
- logger.debug "Getting FKs for #{table_name}"
89
- @@fks_by_table[table_name] = Array.new
90
- @conn.foreign_key_constraints(table_name).each do |fk|
91
- logger.debug "Got one: #{fk}"
92
- @@fks_by_table[table_name].push(fk)
93
- end # do each fk
94
-
95
- end # each table
96
- end
97
-
98
- # Try to work out our link tables now...
99
- @@models.keys.sort.each{|klass| process_table(@@models[klass.to_s])}
100
- @@link_tables.keys.sort.each{|table_name| process_link_table(table_name) if @@link_tables[table_name]}
101
-
102
-
103
- end
84
+ # deal with reserved tables & link_tables && other stray id-less tables
85
+ #key = 'id'
86
+ #case ActiveRecord::Base.primary_key_prefix_type
87
+ # when :table_name
88
+ # key = Inflector.foreign_key(table_name, false)
89
+ # when :table_name_with_underscore
90
+ # key = Inflector.foreign_key(table_name)
91
+ #end
92
+ #next if ReservedTables.include?(table_name.downcase.to_sym) ||
93
+ # is_link_table?(table_name) ||
94
+ # ! @conn.columns(table_name).map{ |x| x.name}.include?(key)
104
95
 
105
- def process_table(table_name)
106
-
107
- logger.debug "Processing model table #{table_name}"
108
-
109
- # ok, so let's look at the foreign keys on the table...
110
- belongs_to_klass = @@tables[table_name].constantize rescue return
111
-
112
- processed_columns = Hash.new
113
-
114
- fks_on_table(table_name).each do |fk|
115
- logger.debug "Found FK column by suffix _id [#{fk.foreign_key}]"
116
- has_some_klass = Inflector.classify(fk.reference_table).constantize rescue next
117
- processed_columns[fk.foreign_key] = { :has_some_klass => has_some_klass }
118
- processed_columns[fk.foreign_key].merge! add_has_some_belongs_to(belongs_to_klass, fk.foreign_key, has_some_klass) rescue next
119
- end
96
+ table_name_clean = table_name.gsub(/^#{@table_name_prefix}/,'')
120
97
 
121
- column_names = @conn.columns(table_name).map{ |x| x.name}
122
- column_names.each do |column_name|
123
- next if not column_name =~ /_id$/
124
- logger.debug "Found FK column by suffix _id [#{column_name}]"
125
- if processed_columns.key?(column_name)
126
- logger.debug "Skipping, already processed"
127
- next
128
- end
129
- has_some_klass = Inflector.classify(column_name.sub(/_id$/,"")).constantize rescue next
130
- processed_columns[column_name] = { :has_some_klass => has_some_klass }
131
- processed_columns[column_name].merge! add_has_some_belongs_to(belongs_to_klass, column_name, has_some_klass) rescue next
132
- end
98
+ # a model table then...
99
+ model_class_name = inflector.class_name(table_name_clean)
133
100
 
134
- #TODO: what if same classes in table?
101
+ logger.debug "Got a model table: #{table_name} => class #{model_class_name}"
135
102
 
136
- # is this a link table with attributes? (has_many through?)
137
- return if processed_columns.keys.length < 2
103
+ @models[model_class_name] = table_name
104
+ @tables[table_name] = model_class_name
138
105
 
139
- processed_columns.keys.each do |key1|
140
- processed_columns.keys.each do |key2|
141
- next if key1 == key2
142
- logger.debug "\n*** #{processed_columns[key1][:has_some_class]}.send 'has_many', #{processed_columns[key2][:belongs_to_name].to_s.pluralize.to_sym}, :through => #{processed_columns[key2][:has_some_name]}\n\n"
143
- processed_columns[key1][:has_some_class].send 'has_many', processed_columns[key2][:belongs_to_name].to_s.pluralize.to_sym, :through => processed_columns[key2][:has_some_name].to_sym
144
- end
145
- end
106
+ if preload
107
+ # create by MAGIC!
108
+ klass = model_class_name.constantize
109
+
110
+ # Process FKs?
111
+ if @conn.supports_fetch_foreign_keys?
146
112
 
113
+ tables.each do |table_name|
114
+ logger.debug "Getting FKs for #{table_name}"
115
+ @fks_by_table[table_name] = Array.new
116
+ @conn.foreign_key_constraints(table_name).each do |fk|
117
+ logger.debug "Got one: #{fk}"
118
+ @fks_by_table[table_name].push(fk)
119
+ end # do each fk
120
+
121
+ end # each table
122
+ end
123
+
124
+ # Try to work out our link tables now...
125
+ @models.keys.sort.each{|klass| process_table(@models[klass.to_s])}
126
+ @link_tables.keys.sort.each{|table_name| process_link_table(table_name) if @link_tables[table_name]}
127
+ end
147
128
  end
148
-
149
-
150
- def add_has_some_belongs_to(belongs_to_klass, belongs_to_fk, has_some_klass)
151
129
 
152
- logger.debug "Trying to add a #{belongs_to_klass} belongs_to #{has_some_klass}..."
130
+ end
131
+
132
+ def process_table(table_name)
153
133
 
154
- # so this is a belongs_to & has_some style relationship...
155
- # is it a has_many, or a has_one? Well, let's assume a has_one has a unique index on the column please... good db design, haha!
156
- unique = belongs_to_klass.get_unique_index_columns.include?(belongs_to_fk)
157
- belongs_to_name = belongs_to_fk.sub(/_id$/, '').to_sym
158
-
159
- logger.debug "\n*** #{belongs_to_klass}.send 'belongs_to', #{belongs_to_name}, :class_name => #{has_some_klass}, :foreign_key => #{belongs_to_fk}\n"
160
- belongs_to_klass.send(:belongs_to, belongs_to_name, :class_name => has_some_klass.to_s, :foreign_key => belongs_to_fk.to_sym)
161
-
162
- # work out if we need a prefix
163
- has_some_name = ((unique ? belongs_to_klass.table_name.singularize : belongs_to_klass.table_name.pluralize) + (belongs_to_name.to_s == has_some_klass.table_name.singularize ? "" : "_as_"+belongs_to_name.to_s)).downcase.to_sym
164
- method = unique ? :has_one : :has_many
165
- logger.debug "\n*** #{has_some_klass}.send(#{method}, #{has_some_name}, :class_name => #{belongs_to_klass.to_s}, :foreign_key => #{belongs_to_fk.to_sym})\n\n"
166
- has_some_klass.send(method, has_some_name, :class_name => belongs_to_klass.to_s, :foreign_key => belongs_to_fk.to_sym)
134
+ logger.debug "Processing model table #{table_name}"
135
+
136
+ # ok, so let's look at the foreign keys on the table...
137
+ belongs_to_klass = @tables[table_name].constantize rescue return
138
+
139
+ processed_columns = Hash.new
140
+
141
+ fks_on_table(table_name).each do |fk|
142
+ logger.debug "Found FK column by suffix _id [#{fk.foreign_key}]"
143
+ has_some_klass = Inflector.classify(fk.reference_table).constantize rescue next
144
+ processed_columns[fk.foreign_key] = { :has_some_klass => has_some_klass }
145
+ processed_columns[fk.foreign_key].merge! add_has_some_belongs_to(belongs_to_klass, fk.foreign_key, has_some_klass) rescue next
146
+ end
147
+
148
+ column_names = @conn.columns(table_name).map{ |x| x.name}
149
+ column_names.each do |column_name|
150
+ next if not column_name =~ /_id$/
151
+ logger.debug "Found FK column by suffix _id [#{column_name}]"
152
+ if processed_columns.key?(column_name)
153
+ logger.debug "Skipping, already processed"
154
+ next
155
+ end
156
+ has_some_klass = Inflector.classify(column_name.sub(/_id$/,"")).constantize rescue next
157
+ processed_columns[column_name] = { :has_some_klass => has_some_klass }
158
+ processed_columns[column_name].merge! add_has_some_belongs_to(belongs_to_klass, column_name, has_some_klass) rescue next
159
+ end
160
+
161
+ #TODO: what if same classes in table?
162
+
163
+ # is this a link table with attributes? (has_many through?)
164
+ return if processed_columns.keys.length < 2
165
+
166
+ processed_columns.keys.each do |key1|
167
+ processed_columns.keys.each do |key2|
168
+ next if key1 == key2
169
+ logger.debug "\n*** #{processed_columns[key1][:has_some_class]}.send 'has_many', #{processed_columns[key2][:belongs_to_name].to_s.pluralize.to_sym}, :through => #{processed_columns[key2][:has_some_name]}\n\n"
170
+ processed_columns[key1][:has_some_class].send 'has_many', processed_columns[key2][:belongs_to_name].to_s.pluralize.to_sym, :through => processed_columns[key2][:has_some_name].to_sym
171
+ end
172
+ end
173
+
174
+ end
175
+
176
+ def add_has_some_belongs_to(belongs_to_klass, belongs_to_fk, has_some_klass)
177
+
178
+ logger.debug "Trying to add a #{belongs_to_klass} belongs_to #{has_some_klass}..."
179
+
180
+ # so this is a belongs_to & has_some style relationship...
181
+ # is it a has_many, or a has_one? Well, let's assume a has_one has a unique index on the column please... good db design, haha!
182
+ unique = belongs_to_klass.get_unique_index_columns.include?(belongs_to_fk)
183
+ belongs_to_name = belongs_to_fk.sub(/_id$/, '').to_sym
184
+
185
+ logger.debug "\n*** #{belongs_to_klass}.send 'belongs_to', #{belongs_to_name}, :class_name => #{has_some_klass}, :foreign_key => #{belongs_to_fk}\n"
186
+ belongs_to_klass.send(:belongs_to, belongs_to_name, :class_name => has_some_klass.to_s, :foreign_key => belongs_to_fk.to_sym)
187
+
188
+ # work out if we need a prefix
189
+ has_some_name = (
190
+ (unique ? belongs_to_klass.table_name.singularize : belongs_to_klass.table_name) +
191
+ (belongs_to_name.to_s == has_some_klass.table_name.singularize ? "" : "_as_"+belongs_to_name.to_s)
192
+ ).downcase.to_sym
193
+ method = unique ? :has_one : :has_many
194
+ logger.debug "\n*** #{has_some_klass}.send(#{method}, #{has_some_name}, :class_name => #{belongs_to_klass.to_s}, :foreign_key => #{belongs_to_fk.to_sym})\n\n"
195
+ has_some_klass.send(method, has_some_name, :class_name => belongs_to_klass.to_s, :foreign_key => belongs_to_fk.to_sym)
196
+
197
+ return { :method => method, :belongs_to_name => belongs_to_name, :has_some_name => has_some_name, :has_some_class => has_some_klass }
167
198
 
168
- return { :method => method, :belongs_to_name => belongs_to_name, :has_some_name => has_some_name, :has_some_class => has_some_klass }
199
+ end
200
+
201
+ def process_link_table(table_name)
202
+
203
+ logger.debug "Processing link table #{table_name}"
169
204
 
205
+ classes_map = Hash.new
206
+ column_names = @conn.columns(table_name).map{ |x| x.name}
207
+
208
+ # use foreign keys first
209
+ fks_on_table(table_name).each do |fk|
210
+ logger.debug "Processing fk: #{fk}"
211
+ klass = Inflector.classify(fk.reference_table).constantize rescue logger.debug("Cannot find model #{class_name} for table #{fk.reference_table}") && return
212
+ classes_map[fk.foreign_key] = klass
170
213
  end
214
+
215
+ logger.debug "Got #{classes_map.keys.length} references from FKs"
216
+
217
+ if classes_map.keys.length < 2
171
218
 
172
- def process_link_table(table_name)
173
-
174
- logger.debug "Processing link table #{table_name}"
175
-
176
- classes_map = Hash.new
177
- column_names = @conn.columns(table_name).map{ |x| x.name}
178
-
179
- # use foreign keys first
180
- fks_on_table(table_name).each do |fk|
181
- logger.debug "Processing fk: #{fk}"
182
- klass = Inflector.classify(fk.reference_table).constantize rescue logger.debug("Cannot find model #{class_name} for table #{fk.reference_table}") && return
183
- classes_map[fk.foreign_key] = klass
184
- end
185
-
186
- logger.debug "Got #{classes_map.keys.length} references from FKs"
187
-
188
- if classes_map.keys.length < 2
189
-
190
- #Fall back on good ol _id recognition
219
+ #Fall back on good ol _id recognition
191
220
 
192
- column_names.each do |column_name|
221
+ column_names.each do |column_name|
193
222
 
194
- # check we haven't processed by fks already
195
- next if ! classes_map[column_name].nil?
196
- referenced_table = column_name.sub(/_id$/, '')
223
+ # check we haven't processed by fks already
224
+ next if ! classes_map[column_name].nil?
225
+ referenced_table = column_name.sub(/_id$/, '')
197
226
 
198
- begin
199
- klass = Inflector.classify(referenced_table).constantize
200
- # fall back on FKs here
201
- if ! klass.nil?
202
- classes_map[column_name] = klass
203
- end
204
- rescue
205
- end
206
- end
227
+ begin
228
+ klass = Inflector.classify(referenced_table).constantize
229
+ # fall back on FKs here
230
+ if ! klass.nil?
231
+ classes_map[column_name] = klass
232
+ end
233
+ rescue
234
+ end
207
235
  end
208
-
209
- # not detected the link table?
210
- logger.debug "Got #{classes_map.keys.length} references"
211
- logger.debug "Cannot detect both tables referenced in link table" && return if classes_map.keys.length != 2
212
-
213
- logger.debug "Adding habtm relationship"
214
-
215
- logger.debug "\n*** #{classes_map[column_names[0]]}.send 'has_and_belongs_to_many', #{column_names[1].sub(/_id$/,'').pluralize.to_sym}, :class_name => #{classes_map[column_names[1]].to_s}, :join_table => #{table_name.to_sym}\n"
216
- logger.debug "\n*** #{classes_map[column_names[1]]}.send 'has_and_belongs_to_many', #{column_names[0].sub(/_id$/,'').pluralize.to_sym}, :class_name => #{classes_map[column_names[0]].to_s}, :join_table => #{table_name.to_sym}\n\n"
217
-
218
- classes_map[column_names[0]].send 'has_and_belongs_to_many', column_names[1].sub(/_id$/,'').pluralize.to_sym, :class_name => classes_map[column_names[1]].to_s, :join_table => table_name.to_sym
219
- classes_map[column_names[1]].send 'has_and_belongs_to_many', column_names[0].sub(/_id$/,'').pluralize.to_sym, :class_name => classes_map[column_names[0]].to_s, :join_table => table_name.to_sym
220
-
221
- end
222
- end
236
+ end
237
+
238
+ # not detected the link table?
239
+ logger.debug "Got #{classes_map.keys.length} references"
240
+ logger.debug "Cannot detect both tables referenced in link table" && return if classes_map.keys.length != 2
241
+
242
+ logger.debug "Adding habtm relationship"
243
+
244
+ logger.debug "\n*** #{classes_map[column_names[0]]}.send 'has_and_belongs_to_many', #{column_names[1].sub(/_id$/,'').pluralize.to_sym}, :class_name => #{classes_map[column_names[1]].to_s}, :join_table => #{table_name.to_sym}\n"
245
+ logger.debug "\n*** #{classes_map[column_names[1]]}.send 'has_and_belongs_to_many', #{column_names[0].sub(/_id$/,'').pluralize.to_sym}, :class_name => #{classes_map[column_names[0]].to_s}, :join_table => #{table_name.to_sym}\n\n"
246
+
247
+ classes_map[column_names[0]].send 'has_and_belongs_to_many', column_names[1].sub(/_id$/,'').pluralize.to_sym, :class_name => classes_map[column_names[1]].to_s, :join_table => table_name.to_sym
248
+ classes_map[column_names[1]].send 'has_and_belongs_to_many', column_names[0].sub(/_id$/,'').pluralize.to_sym, :class_name => classes_map[column_names[0]].to_s, :join_table => table_name.to_sym
249
+
250
+ end
223
251
  end
224
-
252
+
225
253
  class ModelHash < Hash
226
254
  def unenquire(class_id)
227
255
  @enquired ||= {}