has_normalized_sti 1.0.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/.rspec ADDED
File without changes
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source :rubygems
2
+
3
+ group :development do
4
+ gem 'jeweler'
5
+ gem 'mocha'
6
+ gem 'i18n'
7
+ end
8
+
9
+ group :test do
10
+ gem 'rspec'
11
+ gem 'rspec-rails'
12
+ gem 'activerecord', '~> 3.0.0'
13
+ gem 'sqlite3'
14
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,75 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ abstract (1.0.0)
5
+ actionpack (3.0.8)
6
+ activemodel (= 3.0.8)
7
+ activesupport (= 3.0.8)
8
+ builder (~> 2.1.2)
9
+ erubis (~> 2.6.6)
10
+ i18n (~> 0.5.0)
11
+ rack (~> 1.2.1)
12
+ rack-mount (~> 0.6.14)
13
+ rack-test (~> 0.5.7)
14
+ tzinfo (~> 0.3.23)
15
+ activemodel (3.0.8)
16
+ activesupport (= 3.0.8)
17
+ builder (~> 2.1.2)
18
+ i18n (~> 0.5.0)
19
+ activerecord (3.0.8)
20
+ activemodel (= 3.0.8)
21
+ activesupport (= 3.0.8)
22
+ arel (~> 2.0.10)
23
+ tzinfo (~> 0.3.23)
24
+ activesupport (3.0.8)
25
+ arel (2.0.10)
26
+ builder (2.1.2)
27
+ diff-lcs (1.1.2)
28
+ erubis (2.6.6)
29
+ abstract (>= 1.0.0)
30
+ git (1.2.5)
31
+ i18n (0.5.0)
32
+ jeweler (1.6.2)
33
+ bundler (~> 1.0)
34
+ git (>= 1.2.5)
35
+ rake
36
+ mocha (0.9.12)
37
+ rack (1.2.3)
38
+ rack-mount (0.6.14)
39
+ rack (>= 1.0.0)
40
+ rack-test (0.5.7)
41
+ rack (>= 1.0)
42
+ railties (3.0.8)
43
+ actionpack (= 3.0.8)
44
+ activesupport (= 3.0.8)
45
+ rake (>= 0.8.7)
46
+ thor (~> 0.14.4)
47
+ rake (0.9.2)
48
+ rspec (2.6.0)
49
+ rspec-core (~> 2.6.0)
50
+ rspec-expectations (~> 2.6.0)
51
+ rspec-mocks (~> 2.6.0)
52
+ rspec-core (2.6.4)
53
+ rspec-expectations (2.6.0)
54
+ diff-lcs (~> 1.1.2)
55
+ rspec-mocks (2.6.0)
56
+ rspec-rails (2.6.1)
57
+ actionpack (~> 3.0)
58
+ activesupport (~> 3.0)
59
+ railties (~> 3.0)
60
+ rspec (~> 2.6.0)
61
+ sqlite3 (1.3.3)
62
+ thor (0.14.6)
63
+ tzinfo (0.3.28)
64
+
65
+ PLATFORMS
66
+ ruby
67
+
68
+ DEPENDENCIES
69
+ activerecord (~> 3.0.0)
70
+ i18n
71
+ jeweler
72
+ mocha
73
+ rspec
74
+ rspec-rails
75
+ sqlite3
data/README ADDED
@@ -0,0 +1,55 @@
1
+ has_normalized_sti
2
+ ==================
3
+
4
+ This extension will allow Rails STI to work a normalized type column.
5
+
6
+ For example
7
+
8
+ create_table :people, :force => true do |t|
9
+ t.string :full_name
10
+ t.integer :type_id
11
+ end
12
+
13
+ create_table :person_types, :force => true do |t|
14
+ t.string :type_name
15
+ end
16
+
17
+ class Person < ActiveRecord::Base
18
+ has_normalized_sti
19
+ end
20
+
21
+ class PersonType < ActiveRecord::Base
22
+ end
23
+
24
+ after calling has_normalized_sti:
25
+ * type - returns the name of the class of the type just as regular STI
26
+ * type= - set the type to something specific like regular STI
27
+ * normal_type - the Type object through the relation
28
+
29
+
30
+ Configuration options are:
31
+ * type_class_name - belong_to this model for the type storage
32
+ (default: #{class_name}Type)
33
+ * foreign_key - specifies the column for id of the type (default: type_id)
34
+ * type_column - specifies the column name for the type string on the types table
35
+ (default: type_name)
36
+
37
+ Override example
38
+
39
+ create_table :people, :force => true do |t|
40
+ t.string :full_name
41
+ t.integer :special_type_id
42
+ end
43
+
44
+ create_table :person_types, :force => true do |t|
45
+ t.string :special_person_type
46
+ end
47
+
48
+ class SpecialPerson < ActiveRecord::Base
49
+ set_table_name :people
50
+ has_normalized_sti :type_class_name => 'SpecialPersonType', :type_column => 'special_person_type', :foreign_key => 'special_type_id'
51
+ end
52
+
53
+ class SpecialPersonType < ActiveRecord::Base
54
+ set_table_name :person_types
55
+ end
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gem|
4
+ gem.name = 'has_normalized_sti'
5
+ gem.summary = 'allows rails STI to work when the type is normalized out'
6
+ gem.description = <<-DESC
7
+ has_normalzied_sti expects the model to have a type_id column
8
+ referencing a types table containg all the possible types.
9
+ the types table will be auto populated with new types as new
10
+ subclasses are saved
11
+ DESC
12
+ gem.email = 'kevin@glowacz.info'
13
+ gem.author = 'Kevin Glowacz'
14
+ gem.files.exclude '.rvmrc'
15
+ end
16
+ rescue LoadError
17
+ puts 'Jeweler (or a dependency) not available. Install it with: gem install jeweler'
18
+ end
19
+
20
+ require 'rspec/core/rake_task'
21
+ RSpec::Core::RakeTask.new(:spec)
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,59 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{has_normalized_sti}
8
+ s.version = "1.0.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Kevin Glowacz"]
12
+ s.date = %q{2011-06-24}
13
+ s.description = %q{ has_normalzied_sti expects the model to have a type_id column
14
+ referencing a types table containg all the possible types.
15
+ the types table will be auto populated with new types as new
16
+ subclasses are saved
17
+ }
18
+ s.email = %q{kevin@glowacz.info}
19
+ s.extra_rdoc_files = [
20
+ "README"
21
+ ]
22
+ s.files = [
23
+ ".rspec",
24
+ "Gemfile",
25
+ "Gemfile.lock",
26
+ "README",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "has_normalized_sti.gemspec",
30
+ "init.rb",
31
+ "lib/has_normalized_sti.rb",
32
+ "spec/has_normalized_sti_spec.rb",
33
+ "spec/schema.rb",
34
+ "spec/spec_helper.rb",
35
+ "spec/speed_test.rb"
36
+ ]
37
+ s.require_paths = ["lib"]
38
+ s.rubygems_version = %q{1.6.2}
39
+ s.summary = %q{allows rails STI to work when the type is normalized out}
40
+
41
+ if s.respond_to? :specification_version then
42
+ s.specification_version = 3
43
+
44
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
45
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
46
+ s.add_development_dependency(%q<mocha>, [">= 0"])
47
+ s.add_development_dependency(%q<i18n>, [">= 0"])
48
+ else
49
+ s.add_dependency(%q<jeweler>, [">= 0"])
50
+ s.add_dependency(%q<mocha>, [">= 0"])
51
+ s.add_dependency(%q<i18n>, [">= 0"])
52
+ end
53
+ else
54
+ s.add_dependency(%q<jeweler>, [">= 0"])
55
+ s.add_dependency(%q<mocha>, [">= 0"])
56
+ s.add_dependency(%q<i18n>, [">= 0"])
57
+ end
58
+ end
59
+
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'has_normalized_sti'
@@ -0,0 +1,135 @@
1
+ module HasNormalizedSti
2
+ def self.included(base)
3
+ base.extend(ClassMethods)
4
+ end
5
+
6
+ # This extension will allow Rails STI to work a normalized type column.
7
+
8
+ # For example
9
+
10
+ # create_table :people, :force => true do |t|
11
+ # t.string :full_name
12
+ # t.integer :type_id
13
+ # end
14
+
15
+ # create_table :person_types, :force => true do |t|
16
+ # t.string :type_name
17
+ # end
18
+
19
+ # class Person < ActiveRecord::Base
20
+ # has_normalized_sti
21
+ # end
22
+
23
+ # class PersonType < ActiveRecord::Base
24
+ # end
25
+
26
+ # after calling has_normalized_sti:
27
+ # * <tt>type</tt> - returns the name of the class of the type just as regular STI
28
+ # * <tt>type=</tt> - set the type to something specific like regular STI
29
+ # * <tt>normal_type</tt> - the Type object through the relation
30
+ module ClassMethods
31
+ # Configuration options are:
32
+ #
33
+ # * type_class_name - belong_to this model for the type storage
34
+ # (default: #{class_name}Type)
35
+ # * foreign_key - specifies the column for id of the type (default: type_id)
36
+ # * type_column - specifies the column name for the type string on the types table
37
+ # (default: type_name)
38
+ def has_normalized_sti(options = {})
39
+ extend HasNormalizedSti::SingletonMethods
40
+ include HasNormalizedSti::InstanceMethods
41
+
42
+ class_inheritable_accessor :sti_config
43
+ self.sti_config = {
44
+ :type_class_name => "#{table_name.classify}Type",
45
+ :foreign_key => 'type_id',
46
+ :type_column => 'type_name'
47
+ }
48
+ sti_config.update(options)
49
+ sti_config[:type_class_name] = sti_config[:type_class_name].to_s.classify
50
+
51
+ begin
52
+ sti_config[:type_class_name].constantize
53
+ rescue NameError
54
+ txt = "has_normalized_sti could not load #{sti_config[:type_class_name]}\n"
55
+ txt << "please make sure #{sti_config[:type_class_name]} is loaded before #{self.to_s}\n"
56
+ txt << "you might need to add require_dependency '#{sti_config[:type_class_name].underscore}'\n"
57
+ txt << "to #{self.to_s.underscore}.rb"
58
+ raise LoadError, txt
59
+ end
60
+
61
+ belongs_to :normal_type, :class_name => sti_config[:type_class_name], :foreign_key => sti_config[:foreign_key]
62
+ default_scope joins(:normal_type).select("#{table_name}.*, #{sti_config[:type_class_name].constantize.table_name}.#{sti_config[:type_column]}")
63
+ validates_associated :normal_type
64
+ validates_presence_of :normal_type
65
+ end
66
+ end
67
+
68
+ module SingletonMethods
69
+ def instantiate(record)
70
+ if record.has_key?(sti_config[:type_column])
71
+ type_name = record[sti_config[:type_column]]
72
+ else
73
+ associated_record = sti_config[:type_class_name].constantize.find_by_id(record[sti_config[:foreign_key].to_s])
74
+ type_name = associated_record.try(sti_config[:type_column])
75
+ end
76
+ model = find_sti_class(type_name).allocate
77
+ model.init_with('attributes' => record)
78
+ model
79
+ end
80
+
81
+ def find_sti_class(type_name)
82
+ if type_name.blank?
83
+ self
84
+ else
85
+ begin
86
+ if store_full_sti_class
87
+ ActiveSupport::Dependencies.constantize(type_name)
88
+ else
89
+ compute_type(type_name)
90
+ end
91
+ rescue NameError
92
+ raise SubclassNotFound,
93
+ "The single-table inheritance mechanism failed to locate the subclass: '#{type_name}'. " +
94
+ "This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " +
95
+ "Please rename this column if you didn't intend it to be used for storing the inheritance class " +
96
+ "or overwrite #{name}.inheritance_column to use another column for that information."
97
+ end
98
+ end
99
+ end
100
+
101
+ def descends_from_active_record?
102
+ if superclass.abstract_class?
103
+ superclass.descends_from_active_record?
104
+ else
105
+ superclass == ActiveRecord::Base
106
+ end
107
+ end
108
+
109
+ def type_condition
110
+ sti_column = sti_config[:type_class_name].constantize.arel_table[sti_config[:type_column]]
111
+ condition = sti_column.eq(sti_name)
112
+ descendants.each { |subclass| condition = condition.or(sti_column.eq(subclass.sti_name)) }
113
+
114
+ condition
115
+ end
116
+ end
117
+
118
+ module InstanceMethods
119
+ def initialize(attributes = {})
120
+ super
121
+ self.type = self.class.to_s
122
+ end
123
+
124
+ def type
125
+ self.normal_type.try(sti_config[:type_column]) || self.class.to_s
126
+ end
127
+
128
+ def type=(type_name)
129
+ type_class = self.class.sti_config[:type_class_name].constantize
130
+ self.normal_type = type_class.send("find_or_initialize_by_#{sti_config[:type_column]}", type_name)
131
+ end
132
+ end
133
+ end
134
+
135
+ ActiveRecord::Base.send :include, HasNormalizedSti
@@ -0,0 +1,121 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe 'has_normalized_sti' do
4
+ describe 'classes' do
5
+ it 'should hook in to AR:Base' do
6
+ ActiveRecord::Base.should respond_to :has_normalized_sti
7
+ end
8
+ end
9
+
10
+ describe 'instances' do
11
+ before do
12
+ @person = Person.new
13
+ @royal = Royal.new
14
+ @peasant = Peasant.new
15
+ end
16
+
17
+ it 'should respond to type' do
18
+ @person.should respond_to(:type)
19
+ end
20
+
21
+ it 'should have type set to the (sub)class name' do
22
+ @person.type.should == 'Person'
23
+ @royal.type.should == 'Royal'
24
+ @peasant.type.should == 'Peasant'
25
+ end
26
+
27
+ it 'should have an associated normal_type' do
28
+ @person.should respond_to(:normal_type)
29
+ end
30
+
31
+ it 'should have the normal_type be a new record if the type does not exist yet' do
32
+ @person.normal_type.should be_new_record
33
+ end
34
+
35
+ it 'should save the assocated normal_type if it was new' do
36
+ @person.save
37
+ @person.normal_type.should_not be_new_record
38
+ end
39
+
40
+ it 'should not allow a nil normal_type' do
41
+ @person.normal_type = nil
42
+ @person.save.should == false
43
+ @person.should have(1).errors_on(:normal_type)
44
+ end
45
+
46
+ it 'should set the normal_type to an existing record' do
47
+ PersonType.create(:type_name => 'Person')
48
+ Person.new.type_id.should_not be_nil
49
+ Person.new.normal_type.should_not be_new_record
50
+ end
51
+
52
+ it 'should return an object of the subclassed type when searched on the parent' do
53
+ @royal.save!
54
+ person = Person.find(@royal.id)
55
+ person.should be_a(Royal)
56
+ end
57
+
58
+ it 'should allow the type to be set manual and read back' do
59
+ @person.type = 'Royal'
60
+ @person.type.should == 'Royal'
61
+ end
62
+
63
+ it 'should allow a custom type class' do
64
+ @peasant.normal_type.should be_a(SpecialPersonType)
65
+ end
66
+
67
+ it 'should allow a custom foreign key' do
68
+ @peasant.save!
69
+ @peasant.type_id.should be_nil
70
+ @peasant.special_type_id.should_not be_nil
71
+ end
72
+
73
+ it 'should store the type in a custom column' do
74
+ @peasant.normal_type.type_name.should be_nil
75
+ @peasant.normal_type.special_person_type.should == 'Peasant'
76
+ end
77
+
78
+ it 'should be the right object when found from the base' do
79
+ @peasant.save!
80
+ SpecialPerson.find(@peasant.id).should be_a(Peasant)
81
+ end
82
+
83
+ it 'should work with the options as symbols' do
84
+ @farmer = Farmer.new
85
+ @farmer.normal_type.should be_a(SpecialPersonType)
86
+ @farmer.normal_type.type_name.should be_nil
87
+ @farmer.normal_type.special_person_type.should == 'Farmer'
88
+ @farmer.save!
89
+ @farmer.type_id.should be_nil
90
+ @farmer.special_type_id.should_not be_nil
91
+ ReallySpecialPerson.find(@farmer.id).should be_a(Farmer)
92
+ end
93
+
94
+ it 'should error if the type class is not loaded' do
95
+ lambda{
96
+ class ErrPerson < ActiveRecord::Base
97
+ has_normalized_sti :type_class_name => 'NonExistantType'
98
+ end
99
+ }.should raise_error(LoadError)
100
+ end
101
+
102
+ it 'should only return subclassed records' do
103
+ person = Person.create!
104
+ royal = Royal.create!
105
+
106
+ Royal.all.count.should == 1
107
+ end
108
+
109
+ it 'should only return subclassed and subsubclassed' do
110
+ person = Person.create!
111
+ royal = Royal.create!
112
+
113
+ class King < Royal
114
+ end
115
+
116
+ King.create!
117
+ Royal.all.count.should == 2
118
+ end
119
+
120
+ end
121
+ end
data/spec/schema.rb ADDED
@@ -0,0 +1,12 @@
1
+ ActiveRecord::Schema.define(:version => 0) do
2
+ create_table :people, :force => true do |t|
3
+ t.string :full_name
4
+ t.integer :type_id
5
+ t.integer :special_type_id
6
+ end
7
+
8
+ create_table :person_types, :force => true do |t|
9
+ t.string :type_name
10
+ t.string :special_person_type
11
+ end
12
+ end
@@ -0,0 +1,49 @@
1
+ require 'rubygems'
2
+ require 'active_record'
3
+
4
+ require 'rspec'
5
+ require 'rspec/rails/extensions'
6
+ require 'rspec/rails/matchers'
7
+ require 'rspec/rails/adapters'
8
+ require 'rspec/rails/fixture_support'
9
+
10
+ RSpec.configure do |c|
11
+ c.use_transactional_examples = true
12
+ end
13
+
14
+ $:.unshift File.dirname(__FILE__) + '/../lib'
15
+ require File.dirname(__FILE__) + '/../init'
16
+
17
+ ActiveRecord::Base.configurations={'test' => {:adapter => "sqlite3", :database => ":memory:"} }
18
+ ActiveRecord::Base.establish_connection('test')
19
+ load(File.dirname(__FILE__) + "/schema.rb")
20
+
21
+ class PersonType < ActiveRecord::Base
22
+ end
23
+
24
+ class SpecialPersonType < ActiveRecord::Base
25
+ set_table_name :person_types
26
+ end
27
+
28
+ class Person < ActiveRecord::Base
29
+ has_normalized_sti
30
+ end
31
+
32
+ class SpecialPerson < ActiveRecord::Base
33
+ set_table_name :people
34
+ has_normalized_sti :type_class_name => 'SpecialPersonType', :type_column => 'special_person_type', :foreign_key => 'special_type_id'
35
+ end
36
+
37
+ class Royal < Person
38
+ end
39
+
40
+ class Peasant < SpecialPerson
41
+ end
42
+
43
+ class ReallySpecialPerson < ActiveRecord::Base
44
+ set_table_name :people
45
+ has_normalized_sti :type_class_name => :special_person_type, :type_column => :special_person_type, :foreign_key => :special_type_id
46
+ end
47
+
48
+ class Farmer < ReallySpecialPerson
49
+ end
@@ -0,0 +1,32 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ class TestPerson < ActiveRecord::Base
4
+ set_table_name "people"
5
+ set_inheritance_column :full_name
6
+ end
7
+
8
+ control_insert_start = Time.now
9
+ 10000.times do |i|
10
+ TestPerson.create!
11
+ end
12
+ control_insert_end = Time.now
13
+ puts "Baseline insert #{control_insert_end - control_insert_start}"
14
+
15
+ control_select_start = Time.now
16
+ TestPerson.all
17
+ control_select_end = Time.now
18
+ puts "Baseline select #{control_select_end - control_select_start}"
19
+
20
+ TestPerson.delete_all
21
+
22
+ test_insert_start = Time.now
23
+ 10000.times do |i|
24
+ Person.create!
25
+ end
26
+ test_insert_end = Time.now
27
+ puts "Test insert #{test_insert_end - test_insert_start}"
28
+
29
+ test_select_start = Time.now
30
+ Person.all
31
+ test_select_end = Time.now
32
+ puts "Test select #{test_select_end - test_select_start}"
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: has_normalized_sti
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 1.0.0
6
+ platform: ruby
7
+ authors:
8
+ - Kevin Glowacz
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-06-24 00:00:00 -05:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: jeweler
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :development
25
+ prerelease: false
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: mocha
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: i18n
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :development
47
+ prerelease: false
48
+ version_requirements: *id003
49
+ description: " has_normalzied_sti expects the model to have a type_id column\n referencing a types table containg all the possible types.\n the types table will be auto populated with new types as new\n subclasses are saved\n"
50
+ email: kevin@glowacz.info
51
+ executables: []
52
+
53
+ extensions: []
54
+
55
+ extra_rdoc_files:
56
+ - README
57
+ files:
58
+ - .rspec
59
+ - Gemfile
60
+ - Gemfile.lock
61
+ - README
62
+ - Rakefile
63
+ - VERSION
64
+ - has_normalized_sti.gemspec
65
+ - init.rb
66
+ - lib/has_normalized_sti.rb
67
+ - spec/has_normalized_sti_spec.rb
68
+ - spec/schema.rb
69
+ - spec/spec_helper.rb
70
+ - spec/speed_test.rb
71
+ has_rdoc: true
72
+ homepage:
73
+ licenses: []
74
+
75
+ post_install_message:
76
+ rdoc_options: []
77
+
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3468596275297658209
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: "0"
95
+ requirements: []
96
+
97
+ rubyforge_project:
98
+ rubygems_version: 1.6.2
99
+ signing_key:
100
+ specification_version: 3
101
+ summary: allows rails STI to work when the type is normalized out
102
+ test_files: []
103
+