CITIEsForRAILS 0.0.3

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.
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{CITIEsForRAILS}
5
+ s.version = "0.0.3"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Laurent Buffat & Pierre-Emmanuel JOUVE"]
9
+ s.date = %q{2011-02-15}
10
+ s.description = %q{CITIEsForRAILS (Class Inheritance & Table Iheritance Embeddings For RAILS) is a solution that extends Single/Multiple/Class Table Inheritance. This solution is based on classical Ruby class inheritance, single table inheritance as well as DB views.
11
+
12
+
13
+ For Full Information GO TO : http://altrabio.github.com/CITIEsForRAILS/}
14
+ s.email = %q{citiesforrails @nospam@ gmail.com}
15
+ s.extra_rdoc_files = ["lib/citiesforrails.rb", "lib/citiesforrails/acts_as_cities.rb", "lib/citiesforrails/core_ext.rb"]
16
+ s.files = ["Rakefile", "lib/citiesforrails.rb", "lib/citiesforrails/acts_as_cities.rb", "lib/citiesforrails/core_ext.rb", "Manifest", "CITIEsForRAILS.gemspec"]
17
+ s.homepage = %q{https://github.com/altrabio/CITIEsForRAILS}
18
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "CITIEsForRAILS", "--main", "README"]
19
+ s.require_paths = ["lib"]
20
+ s.rubyforge_project = %q{citiesforrails}
21
+ s.rubygems_version = %q{1.3.7}
22
+ s.summary = %q{CITIEsForRAILS (Class Inheritance & Table Iheritance Embeddings For RAILS) is a solution that extends Single/Multiple/Class Table Inheritance. This solution is based on classical Ruby class inheritance, single table inheritance as well as DB views. For Full Information GO TO : http://altrabio.github.com/CITIEsForRAILS/}
23
+
24
+ if s.respond_to? :specification_version then
25
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
26
+ s.specification_version = 3
27
+
28
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
29
+ else
30
+ end
31
+ else
32
+ end
33
+ end
data/Manifest ADDED
@@ -0,0 +1,5 @@
1
+ Rakefile
2
+ lib/citiesforrails.rb
3
+ lib/citiesforrails/acts_as_cities.rb
4
+ lib/citiesforrails/core_ext.rb
5
+ Manifest
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('CITIEsForRAILS', '0.0.3') do |p|
6
+ p.description = "CITIEsForRAILS (Class Inheritance & Table Iheritance Embeddings For RAILS) is a solution that extends Single/Multiple/Class Table Inheritance. This solution is based on classical Ruby class inheritance, single table inheritance as well as DB views.
7
+
8
+
9
+ For Full Information GO TO : http://altrabio.github.com/CITIEsForRAILS/"
10
+ p.url = "https://github.com/altrabio/CITIEsForRAILS"
11
+ p.author = "Laurent Buffat & Pierre-Emmanuel JOUVE"
12
+ p.email = "citiesforrails @nospam@ gmail.com"
13
+ p.ignore_pattern = ["tmp/*", "script/*"]
14
+ p.development_dependencies = []
15
+ end
@@ -0,0 +1,325 @@
1
+ module Cities
2
+
3
+ def self.included(base)
4
+ #When a class includes a module the module’s self.included method will be invoked.
5
+ base.send :extend, ClassMethods
6
+ end
7
+
8
+
9
+ #------------------------------------------------------------------------------------------------------------------------
10
+ #
11
+ # methods that will be used for the class
12
+ #
13
+ #------------------------------------------------------------------------------------------------------------------------
14
+
15
+ module ClassMethods
16
+ # any method placed here will apply to classes
17
+
18
+
19
+ def acts_as_cities(options = {}) #options hash see below
20
+
21
+
22
+ db_type_field = (options[:db_type_field] || :type).to_s #:db_type_field = option for setting the inheritance columns, default value = 'type'
23
+ table_name = (options[:table_name] || self.name.tableize.gsub(/\//,'_')).to_s #:table_name = option for setting the name of the current class table_name, default value = 'tableized(current class name)'
24
+
25
+ set_inheritance_column "#{db_type_field}"
26
+
27
+ if(self.superclass!=ActiveRecord::Base)
28
+ #------------------------------------------------------------------------------------------------------------------------
29
+ #
30
+ # methods that will be used for the NON mother class
31
+ #
32
+ #------------------------------------------------------------------------------------------------------------------------
33
+ puts "acts_as_cities -> NON mother class"
34
+
35
+ set_table_name "view_#{table_name}"
36
+ aaa=create_class_part_of self# these 2 lines are there for the creation of class PartOf (which is a class of the current class)
37
+ self.const_set("PartOf",aaa) # it will stand for the write table of the current class
38
+
39
+
40
+
41
+ def self.delete(id) #overrides delete to delete every pieces of information about this record wherever it may be stored
42
+ if RAILS_ENV == 'development'
43
+ puts "delete de classe = #{self.name}"
44
+ end
45
+ return self.delete(id) if self == self.mother_class #if the class of the record is the mother class then call with the id of the object
46
+ #if the class of the record is not the mother class then
47
+ if RAILS_ENV == 'development'
48
+ puts "2->delete de classe = #{self.name}"
49
+ end
50
+
51
+ if self.respond_to?('has_a_part_of?') # eventually delete pieces of information stored in the table associated to the class of the object (if there is such a table)
52
+ if self.has_a_part_of? && (self.superclass==self.mother_class || self::PartOf!=self.superclass::PartOf) #SHOW TO LB implique moins de SQL
53
+ if RAILS_ENV == 'development'
54
+ puts("has a part of")
55
+ end
56
+ self::PartOf.delete(id)
57
+ else
58
+ if RAILS_ENV == 'development'
59
+ puts "no part of"
60
+ end
61
+ end
62
+ end
63
+
64
+ if RAILS_ENV == 'development'
65
+ puts "3->delete de classe = #{self.name}"
66
+ end
67
+
68
+ self.superclass.delete(id) # call the delete method associated to the super class of the current class with the id the object
69
+ end
70
+
71
+
72
+ send :include, InstanceMethods1
73
+ else
74
+ #------------------------------------------------------------------------------------------------------------------------
75
+ #
76
+ # methods that will be used for the mother class
77
+ #
78
+ #------------------------------------------------------------------------------------------------------------------------
79
+ after_save :updatetype
80
+
81
+
82
+ if RAILS_ENV == 'development'
83
+ puts "acts_as_cities -> MOTHER class"
84
+ end
85
+ set_table_name="#{table_name}"
86
+
87
+ def self.mother_class #returns the mother class (the highest inherited class before ActiveRecord)
88
+ if(self.superclass!=ActiveRecord::Base)
89
+ self.superclass.mother_class
90
+ else
91
+ return self
92
+ end
93
+ end
94
+
95
+
96
+
97
+ def self.find(*args) #overrides find to get more informations
98
+
99
+ tuples = super
100
+ return tuples if tuples.kind_of?(Array) # in case of several tuples just return the tuples as they are
101
+ #tuples.reload2 # reload2 is defined in lib/activerecord_ext.rb
102
+ tuples.class.where(tuples.class[:id].eq(tuples.id))[0] # in case of only one tuple return a reloaded tuple based on the class of this tuple
103
+ # this imply a "full" load of the tuple
104
+ # A VOIR AVEC LB peut être préfère t il laisser reload2
105
+ end
106
+
107
+
108
+ def self.delete_all #contrary to destroy_all this is useful to override this method : In fact destroy_all will explicitly call a destroy method on each object
109
+ #whereas delete_all doesn't and only call a specific SQL request
110
+ # (to be even more precise delete explictly call delete_all with special conditions )
111
+
112
+ self.all.each{|o| o.delete } #call delete method for each instance of the class
113
+
114
+ end
115
+
116
+
117
+
118
+ send :include, InstanceMethods
119
+ end
120
+
121
+
122
+
123
+ end
124
+
125
+ end
126
+
127
+ #------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
128
+
129
+
130
+
131
+
132
+
133
+
134
+ #------------------------------------------------------------------------------------------------------------------------
135
+ #
136
+ # methods that will be used for the instances of the Non Mother Classes
137
+ #
138
+ #------------------------------------------------------------------------------------------------------------------------
139
+
140
+ module InstanceMethods1
141
+
142
+ def save
143
+
144
+
145
+ attributes_for_super = self.attributes.select{|key,value| self.class.superclass.column_names.include?(key) } #get the attributes of the class of the instance that also belong to its superclass
146
+ attributes_for_part_of = self.attributes.select{|key,value| !self.class.superclass.column_names.include?(key) } #get the attributes of the class of the instance that do not belong to its superclass
147
+ # these pieces of information should be stored in the table associated to the class of the instance
148
+ herited = self.class.superclass.new(attributes_for_super) #create a new instance of the superclass of the considered instance (self)
149
+ if(!new_record?)
150
+ herited.swap_new_record
151
+ herited.id = self.id
152
+ end
153
+
154
+ if(herited.class==herited.class.mother_class)
155
+ herited_saved = herited.save # save the new instance (by calling its save method)
156
+ else
157
+ herited_saved = herited.saveBis # save the new instance (by calling its save method)
158
+ end
159
+
160
+ if(herited_saved==false)
161
+ alert('please contact us') # que faire si herited_saved vaut false ? A VOIR
162
+ end
163
+
164
+ part_of_saved=true
165
+ if( ! attributes_for_part_of.empty? ) #if there are some pieces of information to save in the table associated to the class of the considered instance
166
+ part_of = self.class::PartOf.new(attributes_for_part_of)
167
+ part_of.id = herited.id
168
+
169
+ if(!new_record?)
170
+ part_of.swap_new_record
171
+ end
172
+
173
+ part_of_saved = part_of.save
174
+ if(part_of_saved==false)
175
+ alert('please contact us...') # que faire si herited_saved vaut false ? A VOIR
176
+ end
177
+ end
178
+
179
+
180
+ self.id = herited.id
181
+
182
+ sql = "UPDATE #{self.class.mother_class.table_name} SET #{self.class.inheritance_column} = '#{self.class.to_s}' WHERE id = #{self.id}"
183
+ if RAILS_ENV == 'development'
184
+ puts "SQL : #{sql}"
185
+ end
186
+ self.connection.execute(sql)
187
+ return herited_saved && part_of_saved
188
+ end
189
+
190
+
191
+
192
+ def saveBis
193
+
194
+
195
+ attributes_for_super = self.attributes.select{|key,value| self.class.superclass.column_names.include?(key) } #get the attributes of the class of the instance that also belong to its superclass
196
+ attributes_for_part_of = self.attributes.select{|key,value| !self.class.superclass.column_names.include?(key) } #get the attributes of the class of the instance that do not belong to its superclass
197
+ # these pieces of information should be stored in the table associated to the class of the instance
198
+ herited = self.class.superclass.new(attributes_for_super) #create a new instance of the superclass of the considered instance (self)
199
+ if(!new_record?)
200
+ herited.swap_new_record
201
+ herited.id = self.id
202
+ end
203
+
204
+
205
+ if(herited.class==herited.class.mother_class)
206
+ herited_saved = herited.save # save the new instance (by calling its save method)
207
+ else
208
+ herited_saved = herited.saveBis # save the new instance (by calling its save method)
209
+ end
210
+
211
+ if(herited_saved==false)
212
+ alert('please contact altrabio use the following mail : altrabio...altrabio.com') # que faire si herited_saved vaut false ? A VOIR
213
+ end
214
+
215
+ part_of_saved=true
216
+ if( ! attributes_for_part_of.empty? ) #if there are some piecesof information to save in the table associated to the class of the cosidered instance
217
+ part_of = self.class::PartOf.new(attributes_for_part_of) #
218
+ part_of.id = herited.id
219
+
220
+ if(!new_record?)
221
+ part_of.swap_new_record
222
+ end
223
+
224
+ part_of_saved = part_of.save
225
+ if(part_of_saved==false)
226
+ alert('please contact altrabio use the following mail : altrabio...altrabio.com') # que faire si herited_saved vaut false ? A VOIR
227
+ end
228
+ end
229
+
230
+
231
+ self.id = herited.id
232
+
233
+ return herited_saved && part_of_saved
234
+ end
235
+
236
+ def delete #call the class delete method with the id of the instance
237
+ if RAILS_ENV == 'development'
238
+ puts("1-> delete d'instance #{self.id} la classe est #{self.class.name}")
239
+ end
240
+ self.class.delete( self.id)
241
+
242
+ if RAILS_ENV == 'development'
243
+ puts("wl1")
244
+ end
245
+ end
246
+
247
+ end
248
+
249
+
250
+
251
+
252
+
253
+
254
+
255
+
256
+
257
+
258
+ #------------------------------------------------------------------------------------------------------------------------
259
+ #
260
+ # methods that will be used for the instances of the Mother Class
261
+ #
262
+ #------------------------------------------------------------------------------------------------------------------------
263
+
264
+ module InstanceMethods
265
+
266
+
267
+ def updatetype
268
+ sql = "UPDATE #{self.class.mother_class.table_name} SET #{self.class.inheritance_column} = '#{self.class.to_s}' WHERE id = #{self.id}"
269
+ self.connection.execute(sql)
270
+ puts"#{sql}"
271
+ end
272
+
273
+ def destroy
274
+ super
275
+ if self.class.respond_to?('has_a_part_of?')
276
+ qdestroy
277
+ else
278
+ return self
279
+ end
280
+ end
281
+
282
+ def qdestroy
283
+ xxx=self.class
284
+ qqq=xxx
285
+
286
+ while xxx!=ActiveRecord::Base do
287
+
288
+ if xxx.respond_to?('has_a_part_of?') # eventually delete pieces of information stored in the write tables associated to the current xxx class for the object (if there is such a table)
289
+
290
+ if (xxx.superclass==xxx.mother_class || xxx::PartOf!=xxx.superclass::PartOf)
291
+
292
+ puts "partof for class = #{xxx.name}"
293
+ xxx::PartOf.destroy(self.id)
294
+ #oo=xxx::PartOf.find(self.id)
295
+ #oo.destroy
296
+
297
+ else
298
+ puts "no part of for class = #{xxx.name}"
299
+ end#partof
300
+ end #respond
301
+
302
+ qqq=xxx
303
+ xxx=xxx.superclass
304
+
305
+ end #while
306
+
307
+ puts "#{qqq.name} should be the mother class"
308
+ qqq.delete(self.id) #delete information into the table of the mother class
309
+
310
+ return self
311
+ end
312
+
313
+
314
+
315
+
316
+ end
317
+
318
+
319
+
320
+
321
+
322
+ end
323
+ ActiveRecord::Base.send :include, Cities
324
+
325
+
@@ -0,0 +1,282 @@
1
+
2
+
3
+
4
+
5
+
6
+ #------------------------------------------------------------------------------------------------#
7
+ # #
8
+ # Modifications for ActiveRecord #
9
+ # #
10
+ #------------------------------------------------------------------------------------------------#
11
+
12
+ class ActiveRecord::Base
13
+
14
+ def reload
15
+ self.class.find(self.id)
16
+ end
17
+
18
+ def self.[](column_name)
19
+ arel_table[column_name]
20
+ end
21
+
22
+ def swap_new_record # a new own method to arbitrary change the value of the @persisted instance variable
23
+ # (this instance variable is a flag which indicates if a record is a new one or not)
24
+ @persisted=!@persisted
25
+ puts "not persisted"
26
+ end
27
+
28
+
29
+ def self.create_class_part_of(class_reference) #creation of a new class which inherits from ActiveRecord::Base
30
+
31
+ def class_reference.has_a_part_of?
32
+ return true
33
+ end
34
+
35
+ Class.new(ActiveRecord::Base) do
36
+ a=class_reference.table_name
37
+ b=a[5..a.length]
38
+ set_table_name(b)#set the name of the table associated to this class
39
+ # this class will be associated to the write table of the class_reference class
40
+ # consequently the name of the table is the name of the read table without "view_"
41
+
42
+ end
43
+ end
44
+
45
+
46
+ end
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+ #------------------------------------------------------------------------------------------------#
56
+ # #
57
+ # Modifications for ActiveRecord::Persistence #
58
+ # #
59
+ #------------------------------------------------------------------------------------------------#
60
+
61
+ module ActiveRecord
62
+
63
+ module Persistence
64
+
65
+ def destroy
66
+
67
+ if persisted?
68
+ if (self.class.respond_to?("mother_class"))&&(self.class.table_name[0]=="v" && self.class.table_name[1]=="i" && self.class.table_name[2]=="e" && self.class.table_name[3]=="w" && self.class.table_name[4]=="_")
69
+ #if the class of the object is based on this gem and if the considered table is a view
70
+ puts"modified version of ActiveRecord::Persistence destroy"
71
+ puts "class = #{self.class.name} table name=#{self.class.table_name} this is a view : skipping some instructions"
72
+ else
73
+ puts"unmodified version of ActiveRecord::Persistence destroy"
74
+ self.class.unscoped.where(self.class.arel_table[self.class.primary_key].eq(id)).delete_all
75
+ end
76
+ end
77
+
78
+ @destroyed = true
79
+
80
+ freeze
81
+ end
82
+ end
83
+ end
84
+
85
+
86
+
87
+
88
+
89
+ #-----------------------------------------------------------------------------------------------#
90
+ # #
91
+ # Some functions to manage views creation & dropping #
92
+ # #
93
+ #-----------------------------------------------------------------------------------------------#
94
+ def CreateTheViewForCITIEs(theclass) #function for creating views for migrations
95
+
96
+ if RAILS_ENV == 'development'
97
+ puts "CreateTheView 1"
98
+ end
99
+ self_columns = theclass::PartOf.column_names.select{ |c| c != "id" }
100
+ if RAILS_ENV == 'development'
101
+ puts "CreateTheView 2"
102
+ end
103
+ parent_columns = theclass.superclass.column_names.select{ |c| c != "id" }
104
+ columns = parent_columns+self_columns
105
+ if RAILS_ENV == 'development'
106
+ puts "CreateTheView 3"
107
+ end
108
+ self_read_table = theclass.table_name
109
+ # eventuellement warning si pas de part_of
110
+ self_write_table = theclass::PartOf.table_name
111
+ parent_read_table = theclass.superclass.table_name
112
+ if RAILS_ENV == 'development'
113
+ puts "CreateTheView 4"
114
+ end
115
+
116
+ if RAILS_ENV == 'development'
117
+ puts " self read table #{self_read_table} | parent_read_table #{parent_read_table}"
118
+ end
119
+ sql = "CREATE VIEW #{self_read_table} AS SELECT #{parent_read_table}.id, #{columns.join(',')} FROM #{parent_read_table}, #{self_write_table} WHERE #{parent_read_table}.id = #{self_write_table}.id"
120
+ theclass.connection.execute sql
121
+ end
122
+
123
+ def DropTheViewForCITIEs(theclass) #function for dropping views for migrations
124
+ if RAILS_ENV == 'development'
125
+ puts "1 DropTheViewForCITIEs"
126
+ end
127
+ self_read_table = theclass.table_name
128
+
129
+ if RAILS_ENV == 'development'
130
+ puts " DROP VIEW #{self_read_table}"
131
+ end
132
+ sql = "DROP VIEW #{self_read_table}"
133
+ theclass.connection.execute sql
134
+ end
135
+
136
+
137
+ #------------------------------------------------------------------------------------------------#
138
+ # #
139
+ # Modifications for SQL Adapters : needed to take views into account #
140
+ # (only SQLite, PostGreSQL & MySQL has been considered) #
141
+ # #
142
+ #------------------------------------------------------------------------------------------------#
143
+
144
+
145
+ #------------------------------------------------------------------------------------------------#
146
+ # Modifications for SQL Adapters : SQLite #
147
+ #------------------------------------------------------------------------------------------------#
148
+ require 'active_record'
149
+ require 'active_record/connection_adapters/sqlite_adapter'
150
+ require 'active_record/connection_adapters/sqlite3_adapter'
151
+ require 'active_record/connection_adapters/postgresql_adapter'
152
+ module ActiveRecord
153
+ module ConnectionAdapters
154
+ class SQLiteAdapter < AbstractAdapter
155
+
156
+ def tables(name = nil)
157
+ sql = <<-SQL
158
+ SELECT name
159
+ FROM sqlite_master
160
+ WHERE (type = 'table' or type='view') AND NOT name = 'sqlite_sequence'
161
+ SQL
162
+ # Modification : the where clause was intially WHERE type = 'table' AND NOT name = 'sqlite_sequence'
163
+ # now it is WHERE (type = 'table' or type='view') AND NOT name = 'sqlite_sequence'
164
+ # this modification is made to consider tables AND VIEWS as tables
165
+
166
+ execute(sql, name).map do |row|
167
+ row['name']
168
+ end
169
+ end
170
+ end
171
+ end
172
+
173
+ end
174
+
175
+
176
+ #------------------------------------------------------------------------------------------------#
177
+ # Modifications for SQL Adapters : PostGreSQL #
178
+ #------------------------------------------------------------------------------------------------#
179
+
180
+
181
+ module ActiveRecord
182
+ module ConnectionAdapters
183
+ class PostgreSQLAdapter < AbstractAdapter
184
+ def tables(name = nil)
185
+ a=tablesL(name)
186
+ puts("1------>#{a}")
187
+ b=viewsL(name)
188
+ if(b!=[])
189
+ a=a+b
190
+ end
191
+ puts("2------>#{a}")
192
+ return a
193
+ end
194
+
195
+ def tablesL(name = nil)
196
+
197
+ query(<<-SQL, name).map { |row| row[0] }
198
+ SELECT tablename
199
+ FROM pg_tables
200
+ WHERE schemaname = ANY (current_schemas(false))
201
+ SQL
202
+ end
203
+ def viewsL(name = nil)
204
+
205
+ query(<<-SQL, name).map { |row| row[0] }
206
+ SELECT viewname
207
+ FROM pg_views
208
+ WHERE schemaname = ANY (current_schemas(false))
209
+ SQL
210
+ end
211
+
212
+ def table_exists?(name)
213
+ a=table_existsB?(name)
214
+ b=views_existsB?(name)
215
+ puts"T---->#{a}"
216
+ puts"T---->#{b}"
217
+ return a||b
218
+ end
219
+
220
+
221
+ def table_existsB?(name)
222
+ name = name.to_s
223
+ schema, table = name.split('.', 2)
224
+
225
+ unless table # A table was provided without a schema
226
+ table = schema
227
+ schema = nil
228
+ end
229
+
230
+ if name =~ /^"/ # Handle quoted table names
231
+ table = name
232
+ schema = nil
233
+ end
234
+
235
+ query(<<-SQL).first[0].to_i > 0
236
+ SELECT COUNT(*)
237
+ FROM pg_tables
238
+ WHERE tablename = '#{table.gsub(/(^"|"$)/,'')}'
239
+ #{schema ? "AND schemaname = '#{schema}'" : ''}
240
+ SQL
241
+
242
+ end
243
+ def views_existsB?(name)
244
+ name = name.to_s
245
+ schema, table = name.split('.', 2)
246
+
247
+ unless table # A table was provided without a schema
248
+ table = schema
249
+ schema = nil
250
+ end
251
+
252
+ if name =~ /^"/ # Handle quoted table names
253
+ table = name
254
+ schema = nil
255
+ end
256
+
257
+ query(<<-SQL).first[0].to_i > 0
258
+ SELECT COUNT(*)
259
+ FROM pg_views
260
+ WHERE viewname = '#{table.gsub(/(^"|"$)/,'')}'
261
+ #{schema ? "AND schemaname = '#{schema}'" : ''}
262
+ SQL
263
+
264
+ end
265
+ end
266
+ end
267
+ end
268
+
269
+
270
+
271
+ #------------------------------------------------------------------------------------------------#
272
+ # Modifications for SQL Adapters : MySQL #
273
+ #------------------------------------------------------------------------------------------------#
274
+
275
+ # No Modification needed, this essentially comes from the fact that MySQL "show" command
276
+ # lists simultaneously tables & views
277
+
278
+
279
+
280
+
281
+
282
+ # ------------------------------------------------------------- #
@@ -0,0 +1,3 @@
1
+
2
+ require 'citiesforrails/core_ext'
3
+ require 'citiesforrails/acts_as_cities'
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: CITIEsForRAILS
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 3
9
+ version: 0.0.3
10
+ platform: ruby
11
+ authors:
12
+ - Laurent Buffat & Pierre-Emmanuel JOUVE
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-02-15 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: |-
22
+ CITIEsForRAILS (Class Inheritance & Table Iheritance Embeddings For RAILS) is a solution that extends Single/Multiple/Class Table Inheritance. This solution is based on classical Ruby class inheritance, single table inheritance as well as DB views.
23
+
24
+
25
+ For Full Information GO TO : http://altrabio.github.com/CITIEsForRAILS/
26
+ email: citiesforrails @nospam@ gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - lib/citiesforrails.rb
33
+ - lib/citiesforrails/acts_as_cities.rb
34
+ - lib/citiesforrails/core_ext.rb
35
+ files:
36
+ - Rakefile
37
+ - lib/citiesforrails.rb
38
+ - lib/citiesforrails/acts_as_cities.rb
39
+ - lib/citiesforrails/core_ext.rb
40
+ - Manifest
41
+ - CITIEsForRAILS.gemspec
42
+ has_rdoc: true
43
+ homepage: https://github.com/altrabio/CITIEsForRAILS
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options:
48
+ - --line-numbers
49
+ - --inline-source
50
+ - --title
51
+ - CITIEsForRAILS
52
+ - --main
53
+ - README
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ segments:
62
+ - 0
63
+ version: "0"
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ segments:
70
+ - 1
71
+ - 2
72
+ version: "1.2"
73
+ requirements: []
74
+
75
+ rubyforge_project: citiesforrails
76
+ rubygems_version: 1.3.7
77
+ signing_key:
78
+ specification_version: 3
79
+ summary: "CITIEsForRAILS (Class Inheritance & Table Iheritance Embeddings For RAILS) is a solution that extends Single/Multiple/Class Table Inheritance. This solution is based on classical Ruby class inheritance, single table inheritance as well as DB views. For Full Information GO TO : http://altrabio.github.com/CITIEsForRAILS/"
80
+ test_files: []
81
+