citier 0.1.9
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/Manifest +10 -0
- data/Rakefile +14 -0
- data/citier.gemspec +44 -0
- data/lib/citier.rb +27 -0
- data/lib/citier/acts_as_citier.rb +8 -0
- data/lib/citier/child_instance_methods.rb +51 -0
- data/lib/citier/class_methods.rb +77 -0
- data/lib/citier/core_ext.rb +49 -0
- data/lib/citier/instance_methods.rb +30 -0
- data/lib/citier/root_instance_methods.rb +5 -0
- data/lib/citier/sql_adapters.rb +131 -0
- metadata +91 -0
data/Manifest
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
Rakefile
|
2
|
+
lib/citier.rb
|
3
|
+
lib/citier/acts_as_citier.rb
|
4
|
+
lib/citier/child_instance_methods.rb
|
5
|
+
lib/citier/class_methods.rb
|
6
|
+
lib/citier/core_ext.rb
|
7
|
+
lib/citier/instance_methods.rb
|
8
|
+
lib/citier/root_instance_methods.rb
|
9
|
+
lib/citier/sql_adapters.rb
|
10
|
+
Manifest
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'echoe'
|
4
|
+
|
5
|
+
Echoe.new('citier', '0.1.9') do |p|
|
6
|
+
p.description = "CITIER (Class Inheritance & Table Inheritance Embeddings for Rails) is a solution for single and multiple class table inheritance.
|
7
|
+
For full information: http://peterhamilton.github.com/citier/
|
8
|
+
For the original version by ALTRABio see www.github.com/altrabio/"
|
9
|
+
p.url = "https://github.com/peterhamilton/citier/"
|
10
|
+
p.author = "Peter Hamilton, Original Authors - Laurent Buffat, Pierre-Emmanuel Jouve & "
|
11
|
+
p.email = "peter@inspiredpixel.net"
|
12
|
+
p.ignore_pattern = ["tmp/*", "script/*", 'doc/*']
|
13
|
+
p.development_dependencies = []
|
14
|
+
end
|
data/citier.gemspec
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{citier}
|
5
|
+
s.version = "0.1.9"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Peter Hamilton, Originally from Laurent Buffat, Pierre-Emmanuel Jouve"]
|
9
|
+
s.date = %q{2011-04-29}
|
10
|
+
s.description = %q{CITIER (Class Inheritance & Table Inheritance Embeddings for Rails) is a solution for single and multiple class table inheritance.
|
11
|
+
For full information: http://peterhamilton.github.com/citier/
|
12
|
+
For the original version by ALTRABio see www.github.com/altrabio/}
|
13
|
+
s.email = %q{peter@inspiredpixel.net}
|
14
|
+
s.extra_rdoc_files = ["lib/citier.rb",
|
15
|
+
"lib/citier/acts_as_citier.rb",
|
16
|
+
"lib/citier/core_ext.rb",
|
17
|
+
"lib/citier/class_methods.rb",
|
18
|
+
"lib/citier/instance_methods.rb",
|
19
|
+
"lib/citier/child_instance_methods.rb",
|
20
|
+
"lib/citier/root_instance_methods.rb",
|
21
|
+
"lib/citier/sql_adapters.rb"]
|
22
|
+
s.files = ["Rakefile",
|
23
|
+
"lib/citier.rb",
|
24
|
+
"lib/citier/acts_as_citier.rb",
|
25
|
+
"lib/citier/core_ext.rb",
|
26
|
+
"lib/citier/class_methods.rb",
|
27
|
+
"lib/citier/instance_methods.rb",
|
28
|
+
"lib/citier/child_instance_methods.rb",
|
29
|
+
"lib/citier/root_instance_methods.rb",
|
30
|
+
"lib/citier/sql_adapters.rb",
|
31
|
+
"Manifest",
|
32
|
+
"citier.gemspec"]
|
33
|
+
s.homepage = %q{https://github.com/peterhamilton/citier/}
|
34
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "citier", "--main", "README"]
|
35
|
+
s.require_paths = ["lib"]
|
36
|
+
s.rubyforge_project = %q{citier}
|
37
|
+
s.rubygems_version = %q{1.3.7}
|
38
|
+
s.summary = s.description
|
39
|
+
|
40
|
+
if s.respond_to? :specification_version then
|
41
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
42
|
+
s.specification_version = 3
|
43
|
+
end
|
44
|
+
end
|
data/lib/citier.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
CITIER_DEBUGGING = (::Rails.env == 'development')
|
2
|
+
|
3
|
+
def citier_debug(s)
|
4
|
+
if CITIER_DEBUGGING
|
5
|
+
puts "citier -> " + s
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'citier/core_ext'
|
10
|
+
|
11
|
+
# Methods which will be used by the class
|
12
|
+
require 'citier/class_methods'
|
13
|
+
|
14
|
+
# Methods that will be used for the instances of the Non Root Classes
|
15
|
+
require 'citier/instance_methods'
|
16
|
+
|
17
|
+
# Methods that will be used for the instances of the Root Classes
|
18
|
+
require 'citier/root_instance_methods'
|
19
|
+
|
20
|
+
# Methods that will be used for the instances of the Non Root Classes
|
21
|
+
require 'citier/child_instance_methods'
|
22
|
+
|
23
|
+
# Require SQL Adapters
|
24
|
+
require 'citier/sql_adapters'
|
25
|
+
|
26
|
+
#Require acts_as_citier hook
|
27
|
+
require 'citier/acts_as_citier'
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module ChildInstanceMethods
|
2
|
+
|
3
|
+
def save
|
4
|
+
|
5
|
+
#get the attributes of the class which are inherited from it's parent.
|
6
|
+
attributes_for_parent = self.attributes.reject{|key,value| !self.class.superclass.column_names.include?(key) }
|
7
|
+
|
8
|
+
# Get the attributes of the class which are unique to this class and not inherited.
|
9
|
+
attributes_for_current = self.attributes.reject{|key,value| self.class.superclass.column_names.include?(key) }
|
10
|
+
|
11
|
+
citier_debug("Attributes for #{self.class.to_s}: #{attributes_for_current.inspect.to_s}")
|
12
|
+
|
13
|
+
#create a new instance of the superclass, passing the inherited attributes.
|
14
|
+
parent = self.class.superclass.new(attributes_for_parent)
|
15
|
+
parent.id = self.id
|
16
|
+
|
17
|
+
parent.is_new_record(new_record?)
|
18
|
+
|
19
|
+
parent_saved = parent.save
|
20
|
+
self.id = parent.id
|
21
|
+
|
22
|
+
if(parent_saved==false)
|
23
|
+
# Couldn't save parent class
|
24
|
+
# TODO: Handle situation where parent class could not be saved
|
25
|
+
citier_debug("Class (#{self.class.superclass.to_s}) could not be saved")
|
26
|
+
end
|
27
|
+
|
28
|
+
# If there are attributes for the current class (unique & not inherited)
|
29
|
+
# and parent(s) saved successfully, save current model
|
30
|
+
if(!attributes_for_current.empty? && parent_saved)
|
31
|
+
current = self.class::Writable.new(attributes_for_current)
|
32
|
+
current.is_new_record(new_record?)
|
33
|
+
current_saved = current.save
|
34
|
+
|
35
|
+
# This is no longer a new record
|
36
|
+
is_new_record(false)
|
37
|
+
|
38
|
+
if(!current_saved)
|
39
|
+
citier_debug("Class (#{self.class.superclass.to_s}) could not be saved")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Update root class with this 'type'
|
44
|
+
sql = "UPDATE #{self.class.root_class.table_name} SET #{self.class.inheritance_column} = '#{self.class.to_s}' WHERE id = #{self.id}"
|
45
|
+
citier_debug("SQL : #{sql}")
|
46
|
+
self.connection.execute(sql)
|
47
|
+
return parent_saved && current_saved
|
48
|
+
end
|
49
|
+
|
50
|
+
include InstanceMethods
|
51
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module ClassMethods
|
2
|
+
# any method placed here will apply to classes
|
3
|
+
|
4
|
+
|
5
|
+
def acts_as_citier(options = {})
|
6
|
+
|
7
|
+
# Option for setting the inheritance columns, default value = 'type'
|
8
|
+
db_type_field = (options[:db_type_field] || :type).to_s
|
9
|
+
|
10
|
+
#:table_name = option for setting the name of the current class table_name, default value = 'tableized(current class name)'
|
11
|
+
table_name = (options[:table_name] || self.name.tableize.gsub(/\//,'_')).to_s
|
12
|
+
|
13
|
+
set_inheritance_column "#{db_type_field}"
|
14
|
+
|
15
|
+
if(self.superclass!=ActiveRecord::Base)
|
16
|
+
# Non root-class
|
17
|
+
|
18
|
+
citier_debug("Non Root Class")
|
19
|
+
citier_debug("table_name -> #{table_name}")
|
20
|
+
|
21
|
+
# Set up the table which contains ALL attributes we want for this class
|
22
|
+
set_table_name "view_#{table_name}"
|
23
|
+
|
24
|
+
citier_debug("tablename (view) -> #{self.table_name}")
|
25
|
+
|
26
|
+
# The the Writable. References the write-able table for the class because
|
27
|
+
# save operations etc can't take place on the views
|
28
|
+
self.const_set("Writable", create_class_writable(self))
|
29
|
+
|
30
|
+
# Add the functions required for children only
|
31
|
+
send :include, ChildInstanceMethods
|
32
|
+
else
|
33
|
+
# Root class
|
34
|
+
|
35
|
+
after_save :updatetype
|
36
|
+
|
37
|
+
citier_debug("Root Class")
|
38
|
+
|
39
|
+
set_table_name "#{table_name}"
|
40
|
+
|
41
|
+
citier_debug("table_name -> #{self.table_name}")
|
42
|
+
|
43
|
+
#returns the root class (the highest inherited class before ActiveRecord)
|
44
|
+
def self.root_class
|
45
|
+
if(self.superclass!=ActiveRecord::Base)
|
46
|
+
self.superclass.root_class
|
47
|
+
else
|
48
|
+
return self
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.find(*args) #overrides find to get all attributes
|
53
|
+
tuples = super
|
54
|
+
|
55
|
+
# in case of many objects, return an array of them, reloaded to pull in inherited attributes
|
56
|
+
return tuples.map{|x| x.reload} if tuples.kind_of?(Array)
|
57
|
+
|
58
|
+
# in case of only one tuple, return it reloaded.
|
59
|
+
# Can't use reload as would loop inifinitely, so do a search by id instead.
|
60
|
+
# Probably a nice way of cleaning this a bit
|
61
|
+
return tuples.class.where(tuples.class[:id].eq(tuples.id))[0]
|
62
|
+
end
|
63
|
+
|
64
|
+
# Unlike destroy_all it is useful to override this method.
|
65
|
+
# In fact destroy_all will explicitly call a destroy method on each object
|
66
|
+
# whereas delete_all doesn't and only calls specific SQL requests.
|
67
|
+
# To be even more precise call delete_all with special conditions
|
68
|
+
def self.delete_all
|
69
|
+
#call delete method for each instance of the class
|
70
|
+
self.all.each{|o| o.delete }
|
71
|
+
end
|
72
|
+
|
73
|
+
# Add the functions required for root classes only
|
74
|
+
send :include, RootInstanceMethods
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class ActiveRecord::Base
|
2
|
+
|
3
|
+
def self.[](column_name)
|
4
|
+
arel_table[column_name]
|
5
|
+
end
|
6
|
+
|
7
|
+
def is_new_record(state)
|
8
|
+
@new_record = state
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.all(*args)
|
12
|
+
# For some reason need to override this so it uses my modified find function which reloads each object to pull in all properties.
|
13
|
+
return find(:all, *args)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.create_class_writable(class_reference) #creation of a new class which inherits from ActiveRecord::Base
|
17
|
+
Class.new(ActiveRecord::Base) do
|
18
|
+
t_name = class_reference.table_name
|
19
|
+
t_name = t_name[5..t_name.length]
|
20
|
+
|
21
|
+
if t_name[0..5] == "view_"
|
22
|
+
t_name = t_name[5..t_name.length]
|
23
|
+
end
|
24
|
+
|
25
|
+
# set the name of the table associated to this class
|
26
|
+
# this class will be associated to the writable table of the class_reference class
|
27
|
+
set_table_name(t_name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_citier_view(theclass) #function for creating views for migrations
|
33
|
+
self_columns = theclass::Writable.column_names.select{ |c| c != "id" }
|
34
|
+
parent_columns = theclass.superclass.column_names.select{ |c| c != "id" }
|
35
|
+
columns = parent_columns+self_columns
|
36
|
+
self_read_table = theclass.table_name
|
37
|
+
self_write_table = theclass::Writable.table_name
|
38
|
+
parent_read_table = theclass.superclass.table_name
|
39
|
+
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"
|
40
|
+
citier_debug("Creating citier view -> #{sql}")
|
41
|
+
theclass.connection.execute sql
|
42
|
+
end
|
43
|
+
|
44
|
+
def drop_citier_view(theclass) #function for dropping views for migrations
|
45
|
+
self_read_table = theclass.table_name
|
46
|
+
sql = "DROP VIEW #{self_read_table}"
|
47
|
+
citier_debug("Dropping citier view -> #{sql}")
|
48
|
+
theclass.connection.execute sql
|
49
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module InstanceMethods
|
2
|
+
|
3
|
+
# Delete the model (and all parents it inherits from if applicable)
|
4
|
+
def delete(id = self.id)
|
5
|
+
citier_debug("Deleting #{self.class.to_s} with ID #{self.id}")
|
6
|
+
|
7
|
+
# Delete information stored in the table associated to the class of the object
|
8
|
+
# (if there is such a table)
|
9
|
+
deleted = true
|
10
|
+
c = self.class
|
11
|
+
while c.superclass!=ActiveRecord::Base
|
12
|
+
citier_debug("Deleting back up hierarchy #{c}")
|
13
|
+
deleted &= c::Writable.delete(id)
|
14
|
+
c = c.superclass
|
15
|
+
end
|
16
|
+
deleted &= c.delete(id)
|
17
|
+
return deleted
|
18
|
+
end
|
19
|
+
|
20
|
+
def updatetype
|
21
|
+
sql = "UPDATE #{self.class.root_class.table_name} SET #{self.class.inheritance_column} = '#{self.class.to_s}' WHERE id = #{self.id}"
|
22
|
+
self.connection.execute(sql)
|
23
|
+
citier_debug("#{sql}")
|
24
|
+
end
|
25
|
+
|
26
|
+
def destroy
|
27
|
+
return self.delete
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
#------------------------------------------------------------------------------------------------#
|
2
|
+
# #
|
3
|
+
# Modifications for SQL Adapters : needed to take views into account #
|
4
|
+
# (only SQLite, PostGreSQL & MySQL have been considered) #
|
5
|
+
# #
|
6
|
+
#------------------------------------------------------------------------------------------------#
|
7
|
+
|
8
|
+
# SQLite
|
9
|
+
|
10
|
+
require 'active_record'
|
11
|
+
require 'active_record/connection_adapters/sqlite_adapter'
|
12
|
+
require 'active_record/connection_adapters/sqlite3_adapter'
|
13
|
+
require 'active_record/connection_adapters/postgresql_adapter'
|
14
|
+
module ActiveRecord
|
15
|
+
module ConnectionAdapters
|
16
|
+
class SQLiteAdapter < AbstractAdapter
|
17
|
+
|
18
|
+
def tables(name = nil)
|
19
|
+
sql = <<-SQL
|
20
|
+
SELECT name
|
21
|
+
FROM sqlite_master
|
22
|
+
WHERE (type = 'table' or type='view') AND NOT name = 'sqlite_sequence'
|
23
|
+
SQL
|
24
|
+
# Modification : the where clause was intially WHERE type = 'table' AND NOT name = 'sqlite_sequence'
|
25
|
+
# now it is WHERE (type = 'table' or type='view') AND NOT name = 'sqlite_sequence'
|
26
|
+
# this modification is made to consider tables AND VIEWS as tables
|
27
|
+
|
28
|
+
execute(sql, name).map do |row|
|
29
|
+
row['name']
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
# PostGreSQL
|
39
|
+
module ActiveRecord
|
40
|
+
module ConnectionAdapters
|
41
|
+
class PostgreSQLAdapter < AbstractAdapter
|
42
|
+
def tables(name = nil)
|
43
|
+
a=tablesL(name)
|
44
|
+
puts("1------>#{a}")
|
45
|
+
b=viewsL(name)
|
46
|
+
if(b!=[])
|
47
|
+
a=a+b
|
48
|
+
end
|
49
|
+
puts("2------>#{a}")
|
50
|
+
return a
|
51
|
+
end
|
52
|
+
|
53
|
+
def tablesL(name = nil)
|
54
|
+
|
55
|
+
query(<<-SQL, name).map { |row| row[0] }
|
56
|
+
SELECT tablename
|
57
|
+
FROM pg_tables
|
58
|
+
WHERE schemaname = ANY (current_schemas(false))
|
59
|
+
SQL
|
60
|
+
end
|
61
|
+
def viewsL(name = nil)
|
62
|
+
|
63
|
+
query(<<-SQL, name).map { |row| row[0] }
|
64
|
+
SELECT viewname
|
65
|
+
FROM pg_views
|
66
|
+
WHERE schemaname = ANY (current_schemas(false))
|
67
|
+
SQL
|
68
|
+
end
|
69
|
+
|
70
|
+
def table_exists?(name)
|
71
|
+
a=table_existsB?(name)
|
72
|
+
b=views_existsB?(name)
|
73
|
+
puts"T---->#{a}"
|
74
|
+
puts"T---->#{b}"
|
75
|
+
return a||b
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
def table_existsB?(name)
|
80
|
+
name = name.to_s
|
81
|
+
schema, table = name.split('.', 2)
|
82
|
+
|
83
|
+
unless table # A table was provided without a schema
|
84
|
+
table = schema
|
85
|
+
schema = nil
|
86
|
+
end
|
87
|
+
|
88
|
+
if name =~ /^"/ # Handle quoted table names
|
89
|
+
table = name
|
90
|
+
schema = nil
|
91
|
+
end
|
92
|
+
|
93
|
+
query(<<-SQL).first[0].to_i > 0
|
94
|
+
SELECT COUNT(*)
|
95
|
+
FROM pg_tables
|
96
|
+
WHERE tablename = '#{table.gsub(/(^"|"$)/,'')}'
|
97
|
+
#{schema ? "AND schemaname = '#{schema}'" : ''}
|
98
|
+
SQL
|
99
|
+
|
100
|
+
end
|
101
|
+
def views_existsB?(name)
|
102
|
+
name = name.to_s
|
103
|
+
schema, table = name.split('.', 2)
|
104
|
+
|
105
|
+
unless table # A table was provided without a schema
|
106
|
+
table = schema
|
107
|
+
schema = nil
|
108
|
+
end
|
109
|
+
|
110
|
+
if name =~ /^"/ # Handle quoted table names
|
111
|
+
table = name
|
112
|
+
schema = nil
|
113
|
+
end
|
114
|
+
|
115
|
+
query(<<-SQL).first[0].to_i > 0
|
116
|
+
SELECT COUNT(*)
|
117
|
+
FROM pg_views
|
118
|
+
WHERE viewname = '#{table.gsub(/(^"|"$)/,'')}'
|
119
|
+
#{schema ? "AND schemaname = '#{schema}'" : ''}
|
120
|
+
SQL
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
# MySQL
|
130
|
+
# No Modification needed, this essentially comes from the fact that MySQL "show" command
|
131
|
+
# lists simultaneously tables & views
|
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: citier
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 9
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 9
|
10
|
+
version: 0.1.9
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Peter Hamilton, Originally from Laurent Buffat, Pierre-Emmanuel Jouve
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-04-29 00:00:00 Z
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: |-
|
22
|
+
CITIER (Class Inheritance & Table Inheritance Embeddings for Rails) is a solution for single and multiple class table inheritance.
|
23
|
+
For full information: http://peterhamilton.github.com/citier/
|
24
|
+
For the original version by ALTRABio see www.github.com/altrabio/
|
25
|
+
email: peter@inspiredpixel.net
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- lib/citier.rb
|
32
|
+
- lib/citier/acts_as_citier.rb
|
33
|
+
- lib/citier/core_ext.rb
|
34
|
+
- lib/citier/class_methods.rb
|
35
|
+
- lib/citier/instance_methods.rb
|
36
|
+
- lib/citier/child_instance_methods.rb
|
37
|
+
- lib/citier/root_instance_methods.rb
|
38
|
+
- lib/citier/sql_adapters.rb
|
39
|
+
files:
|
40
|
+
- Rakefile
|
41
|
+
- lib/citier.rb
|
42
|
+
- lib/citier/acts_as_citier.rb
|
43
|
+
- lib/citier/core_ext.rb
|
44
|
+
- lib/citier/class_methods.rb
|
45
|
+
- lib/citier/instance_methods.rb
|
46
|
+
- lib/citier/child_instance_methods.rb
|
47
|
+
- lib/citier/root_instance_methods.rb
|
48
|
+
- lib/citier/sql_adapters.rb
|
49
|
+
- Manifest
|
50
|
+
- citier.gemspec
|
51
|
+
homepage: https://github.com/peterhamilton/citier/
|
52
|
+
licenses: []
|
53
|
+
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options:
|
56
|
+
- --line-numbers
|
57
|
+
- --inline-source
|
58
|
+
- --title
|
59
|
+
- citier
|
60
|
+
- --main
|
61
|
+
- README
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
hash: 3
|
70
|
+
segments:
|
71
|
+
- 0
|
72
|
+
version: "0"
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 11
|
79
|
+
segments:
|
80
|
+
- 1
|
81
|
+
- 2
|
82
|
+
version: "1.2"
|
83
|
+
requirements: []
|
84
|
+
|
85
|
+
rubyforge_project: citier
|
86
|
+
rubygems_version: 1.7.2
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: "CITIER (Class Inheritance & Table Inheritance Embeddings for Rails) is a solution for single and multiple class table inheritance. For full information: http://peterhamilton.github.com/citier/ For the original version by ALTRABio see www.github.com/altrabio/"
|
90
|
+
test_files: []
|
91
|
+
|