multiple_table_inheritance 0.1.3 → 0.1.4

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.
@@ -10,58 +10,57 @@ describe MultipleTableInheritance::Parent do
10
10
  end
11
11
  end
12
12
 
13
- context 'non-namespaced classes' do
13
+ context 'non-namespaced classes with default subtype' do
14
14
  context 'retrieving records' do
15
15
  before do
16
16
  mock_employees!
17
17
  end
18
-
18
+
19
19
  it 'should retrieve child records' do
20
- Employee.find_each do |programmer_or_manager|
21
- programmer_or_manager.should_not be_instance_of(Employee)
22
- ['Programmer', 'Manager'].should include(programmer_or_manager.class.to_s)
20
+ Employee.find_each do |employee_subtype|
21
+ employee_subtype.should_not be_instance_of(Employee)
22
+ ['Programmer', 'Manager', 'Janitor'].should include(employee_subtype.class.to_s)
23
23
  end
24
24
  end
25
-
25
+
26
26
  it 'should allow access to parent record' do
27
- programmer_or_manager = Employee.first
28
- programmer_or_manager.employee.should be_instance_of(Employee)
27
+ employee_subtype = Employee.first
28
+ employee_subtype.employee.should be_instance_of(Employee)
29
29
  end
30
-
30
+
31
31
  it 'should include all records' do
32
32
  modified_results = Employee.all
33
33
  original_results = Employee.as_supertype.all
34
34
  modified_results.size.should == original_results.size
35
35
  end
36
-
36
+
37
37
  it 'should maintain result order' do
38
38
  modified_results = Employee.order("id desc").all
39
39
  original_results = Employee.as_supertype.order("id desc").all
40
40
  modified_results.collect(&:id).should == original_results.collect(&:id)
41
41
  end
42
-
42
+
43
43
  context 'associations preloading' do
44
44
  context 'is enabled' do
45
45
  before do
46
- @programmer_or_manager = Employee.includes(:team).first
46
+ @employee_subtype = Employee.includes(:team).first
47
47
  end
48
-
48
+
49
49
  it 'should not perform an extra find' do
50
- pending "ensure that team is not retrieved from the database"
51
- Team.any_instance.should_not_receive(:find_by_sql)
52
- @programmer_or_manager.employee.team
50
+ Team.should_not_receive(:find_by_sql)
51
+ @employee_subtype.employee.team
53
52
  end
54
53
  end
55
-
54
+
56
55
  context 'is disabled' do
57
56
  before do
58
- @programmer_or_manager = Employee.first
57
+ @employee_subtype = Employee.first
59
58
  end
60
-
59
+
61
60
  it 'should not perform an extra find' do
62
- pending "ensure that team is retrieved from the database"
63
- Team.any_instance.should_receive(:find_by_sql).at_least(:once)
64
- @programmer_or_manager.employee.team
61
+ pending "appears to be an rspec bug preventing this from working"
62
+ Team.should_not_receive(:find_by_sql).with(any_args).once
63
+ @employee_subtype.employee.team
65
64
  end
66
65
  end
67
66
  end
@@ -69,7 +68,7 @@ describe MultipleTableInheritance::Parent do
69
68
 
70
69
  context 'deleting records' do
71
70
  before do
72
- programmer = Programmer.create!(:first_name => 'Billy', :last_name => 'Ray', :salary => 50000, :team => @team)
71
+ programmer = Programmer.create!(:first_name => 'Billy', :last_name => 'Ray', :salary => 50000)
73
72
  @employee = programmer.employee
74
73
  @employee_id = programmer.id
75
74
  end
@@ -87,30 +86,45 @@ describe MultipleTableInheritance::Parent do
87
86
 
88
87
  context 'an invalid subtype exists' do
89
88
  before do
90
- @employee = Employee.create!(:first_name => 'Sub', :last_name => 'Type', :salary => 50000, :team => @team) do |employee|
89
+ @employee = Employee.create!(:first_name => 'Sub', :last_name => 'Type', :salary => 50000) do |employee|
91
90
  employee.subtype = 'DoesNotExist'
92
91
  end
93
92
  end
94
93
 
95
- it 'should return successfully' do
96
- @employee.should be_instance_of(Employee)
94
+ it 'should not have errors' do
95
+ @employee.errors.messages.should be_empty
97
96
  end
98
97
 
99
- it 'should log an error' do
100
- pending "logger.error should have been called"
98
+ it 'should have been saved' do
99
+ @employee.should_not be_new_record
100
+ end
101
+
102
+ context 'retrieving saved record' do
103
+ before do
104
+ @record = Employee.find_by_id(@employee.id)
105
+ end
106
+
107
+ it 'should not return the parent model instance' do
108
+ @record.should be_nil
109
+ end
110
+
111
+ context 'logger exists on model' do
112
+ before do
113
+ require 'logger'
114
+ @logger = Logger.new(nil)
115
+ ActiveRecord::Base.stub(:logger).and_return(@logger)
116
+ end
117
+
118
+ it 'should log a warning' do
119
+ @logger.should_receive(:warn)
120
+ Employee.find_by_id(@employee.id)
121
+ end
122
+ end
101
123
  end
102
- end
103
-
104
- context 'default subtype' do
105
- pending "test_everything"
106
- end
107
-
108
- context 'custom subtype' do
109
- pending "test_everything"
110
124
  end
111
125
  end
112
126
 
113
- context 'namespaced classes' do
127
+ context 'namespaced classes with custom subtype' do
114
128
  context 'retrieving records' do
115
129
  before(:each) do
116
130
  mock_pets!
data/spec/spec_helper.rb CHANGED
@@ -10,7 +10,7 @@ require 'support/models'
10
10
  module MultipleTableInheritanceSpecHelper
11
11
  def mock_employees!
12
12
  3.times do |i|
13
- team = Team.create!(:name => "Team#{i}")
13
+ team = Team.create!(:name => "Team #{i}")
14
14
  language = Language.create!(:name => "Java 1.#{i + 4}")
15
15
  end
16
16
 
@@ -28,6 +28,13 @@ module MultipleTableInheritanceSpecHelper
28
28
  :salary => 70000 + (i * 2500),
29
29
  :team => Team.first,
30
30
  :bonus => i * 2500) # manager-specific field
31
+
32
+ Janitor.create!(
33
+ :first_name => "Phil",
34
+ :last_name => "Moore #{i}",
35
+ :salary => 40000 + (i * 1000),
36
+ :team => Team.last,
37
+ :preferred_cleaner => %w{Comet Windex Swiffer}[i % 3]) # janitor-specific field
31
38
  end
32
39
  end
33
40
 
@@ -39,15 +46,13 @@ module MultipleTableInheritanceSpecHelper
39
46
 
40
47
  dog = Pet::Dog.create!(:name => "Rover #{i}") do |dog|
41
48
  dog.owner = owner
42
- dog.favorite_toy = "#{i + 1}-inch Bone"
49
+ dog.favorite_toy = "#{i + 1}-inch Bone" # dog-specific field
43
50
  end
44
- puts dog.inspect
45
51
 
46
52
  cat = Pet::Cat.create!(:name => "Mittens #{i}") do |cat|
47
53
  cat.owner = owner
48
- cat.longest_nap = 100 + i
54
+ cat.longest_nap = 100 + i # cat-specific field
49
55
  end
50
- puts cat.inspect
51
56
  end
52
57
  end
53
58
  end
@@ -1,6 +1,7 @@
1
- ###############################################
2
- # Non-namespaced models
3
- ###############################################
1
+ #########################################################
2
+ # Non-namespaced models with mass-assignment security
3
+ # everywhere or only on parent.
4
+ #########################################################
4
5
 
5
6
  class Employee < ActiveRecord::Base
6
7
  acts_as_superclass
@@ -9,21 +10,29 @@ class Employee < ActiveRecord::Base
9
10
  validates :first_name, :presence => true
10
11
  validates :last_name, :presence => true
11
12
  validates :salary, :presence => true, :numericality => { :min => 0 }
13
+
14
+ def give_raise!(amount)
15
+ Employee.update_counters self.id, :salary => amount
16
+ end
12
17
  end
13
18
 
14
19
  class Programmer < ActiveRecord::Base
15
- inherits_from :employee
20
+ inherits_from :employee #, :methods => true
16
21
  attr_accessible :languages, :language_ids
17
22
  has_many :known_languages
18
23
  has_many :languages, :through => :known_languages
19
24
  end
20
25
 
21
26
  class Manager < ActiveRecord::Base
22
- inherits_from :employee
27
+ inherits_from :employee #, :methods => true
23
28
  attr_accessible :bonus
24
29
  validates :bonus, :numericality => true
25
30
  end
26
31
 
32
+ class Janitor < ActiveRecord::Base
33
+ inherits_from :employee #, :methods => true
34
+ end
35
+
27
36
  class Team < ActiveRecord::Base
28
37
  attr_accessible :name, :description
29
38
  has_many :employees
@@ -44,9 +53,32 @@ class KnownLanguage < ActiveRecord::Base
44
53
  validates :language_id, :presence => true, :uniqueness => { :scope => :programmer_id }
45
54
  end
46
55
 
47
- ###############################################
48
- # Namespaced models
49
- ###############################################
56
+ #########################################################
57
+ # Non-namespaced models with mass assignment security
58
+ # only on children or not specified.
59
+ #########################################################
60
+
61
+ class Clothing < ActiveRecord::Base
62
+ acts_as_superclass
63
+ validates :color, :presence => true
64
+ end
65
+
66
+ class Shirt < ActiveRecord::Base
67
+ inherits_from :clothing
68
+ attr_accessible :size
69
+ validates :size, :presence => true
70
+ end
71
+
72
+ class Pants < ActiveRecord::Base
73
+ inherits_from :clothing
74
+ validates :waist_size, :presence => true
75
+ validates :length, :presence => true
76
+ end
77
+
78
+ #########################################################
79
+ # Namespaced models with mass assignment security
80
+ # everywhere or only on parent.
81
+ #########################################################
50
82
 
51
83
  module Pet
52
84
  def self.table_name_prefix
@@ -67,13 +99,47 @@ module Pet
67
99
  belongs_to :owner
68
100
  validates :owner_id, :presence => true
69
101
  validates :name, :presence => true
102
+
103
+ def rename!(new_name)
104
+ update_attributes!(:name => new_name)
105
+ end
70
106
  end
71
107
 
72
- class Dog < ActiveRecord::Base
108
+ class Cat < ActiveRecord::Base
73
109
  inherits_from :pet, :class_name => 'Pet::Pet'
110
+ attr_accessible :longest_nap
74
111
  end
75
112
 
76
113
  class Dog < ActiveRecord::Base
77
114
  inherits_from :pet, :class_name => 'Pet::Pet'
78
115
  end
79
116
  end
117
+
118
+ #########################################################
119
+ # Namespaced models with mass assignment security
120
+ # only on children or not specified.
121
+ #########################################################
122
+
123
+ module Store
124
+ def self.table_name_prefix
125
+ 'store_'
126
+ end
127
+
128
+ class Furniture < ActiveRecord::Base
129
+ acts_as_superclass
130
+ validates :brand, :presence => true
131
+ validates :name, :presence => true
132
+ end
133
+
134
+ class Bed < ActiveRecord::Base
135
+ inherits_from :furniture, :class_name => 'Store::Furniture'
136
+ validates :size, :presence => true
137
+ end
138
+
139
+ class Table < ActiveRecord::Base
140
+ inherits_from :furniture, :class_name => 'Store::Furniture'
141
+ attr_accessible :chairs, :color
142
+ validates :chairs, :presence => true, :numericality => { :min => 1 }
143
+ validates :color, :presence => true
144
+ end
145
+ end
@@ -1,14 +1,18 @@
1
- ActiveRecord::Base.establish_connection(
2
- :adapter => 'sqlite3',
3
- :database => File.expand_path(File.join(File.dirname(__FILE__), '../../db/multiple_table_inheritance.db'))
4
- )
1
+ db_path = File.expand_path(File.join(File.dirname(__FILE__), '../../db'))
2
+ db_file = File.join(db_path, 'multiple_table_inheritance.db')
5
3
 
4
+ # Create/Overwrite database file
5
+ File.delete(db_file) if File.exist?(db_file)
6
+ Dir.mkdir(db_path) unless File.directory?(db_path)
7
+ File.open(db_file, 'w') {}
8
+
9
+ # Open a database connection
10
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => db_file)
6
11
  conn = ActiveRecord::Base.connection
7
12
 
8
- TABLES = ['employees', 'programmers', 'managers', 'teams', 'languages', 'known_languages', 'pet_owners', 'pet_pets', 'pet_dogs', 'pet_cats'].freeze
9
- TABLES.each do |table|
10
- conn.execute "DROP TABLE IF EXISTS '#{table}'"
11
- end
13
+ #########################################################
14
+ # Employee entities
15
+ #########################################################
12
16
 
13
17
  conn.create_table :employees do |t|
14
18
  t.string :subtype, :null => false
@@ -25,6 +29,10 @@ conn.create_table :managers, :inherits => :employee do |t|
25
29
  t.integer :bonus
26
30
  end
27
31
 
32
+ conn.create_table :janitors, :inherits => :employee do |t|
33
+ t.string :preferred_cleaner
34
+ end
35
+
28
36
  conn.create_table :teams do |t|
29
37
  t.string :name, :null => false
30
38
  end
@@ -38,6 +46,28 @@ conn.create_table :known_languages do |t|
38
46
  t.integer :language_id, :null => false
39
47
  end
40
48
 
49
+ #########################################################
50
+ # Clothing entities
51
+ #########################################################
52
+
53
+ conn.create_table :clothings do |t|
54
+ t.string :subtype, :null => false
55
+ t.string :color, :null => false
56
+ end
57
+
58
+ conn.create_table :shirts, :inherits => :clothing do |t|
59
+ t.string :size, :limit => 2, :null => false
60
+ end
61
+
62
+ conn.create_table :pants, :inherits => :clothing do |t|
63
+ t.integer :waist_size, :null => false
64
+ t.integer :length, :null => false
65
+ end
66
+
67
+ #########################################################
68
+ # Pet entities
69
+ #########################################################
70
+
41
71
  conn.create_table :pet_owners do |t|
42
72
  t.string :first_name, :null => false
43
73
  t.string :last_name, :null => false
@@ -51,10 +81,29 @@ conn.create_table :pet_pets do |t|
51
81
  t.string :color
52
82
  end
53
83
 
54
- conn.create_table :pet_dogs, :inherits => :pets do |t|
84
+ conn.create_table :pet_dogs, :inherits => :pet do |t|
55
85
  t.string :favorite_toy
56
86
  end
57
87
 
58
- conn.create_table :pet_cats, :inherits => :pets do |t|
88
+ conn.create_table :pet_cats, :inherits => :pet do |t|
59
89
  t.integer :longest_nap
60
90
  end
91
+
92
+ #########################################################
93
+ # Store entities
94
+ #########################################################
95
+
96
+ conn.create_table :store_furnitures do |t|
97
+ t.string :subtype, :null => false
98
+ t.string :brand, :null => false
99
+ t.string :name, :null => false
100
+ end
101
+
102
+ conn.create_table :store_beds, :inherits => :furniture do |t|
103
+ t.string :size, :null => false
104
+ end
105
+
106
+ conn.create_table :store_tables, :inherits => :furniture do |t|
107
+ t.integer :chairs, :null => false
108
+ t.string :color, :null => false
109
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: multiple_table_inheritance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-11 00:00:00.000000000Z
12
+ date: 2012-03-13 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
16
- requirement: &2161139800 !ruby/object:Gem::Requirement
16
+ requirement: &2153195660 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 3.0.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2161139800
24
+ version_requirements: *2153195660
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: activesupport
27
- requirement: &2161139340 !ruby/object:Gem::Requirement
27
+ requirement: &2153195200 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 3.0.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *2161139340
35
+ version_requirements: *2153195200
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec-rails
38
- requirement: &2161138880 !ruby/object:Gem::Requirement
38
+ requirement: &2153194720 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 2.8.0
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2161138880
46
+ version_requirements: *2153194720
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec_tag_matchers
49
- requirement: &2161138420 !ruby/object:Gem::Requirement
49
+ requirement: &2153194240 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.0.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2161138420
57
+ version_requirements: *2153194240
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: sqlite3-ruby
60
- requirement: &2161137960 !ruby/object:Gem::Requirement
60
+ requirement: &2153193740 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 1.3.3
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *2161137960
68
+ version_requirements: *2153193740
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: database_cleaner
71
- requirement: &2161137500 !ruby/object:Gem::Requirement
71
+ requirement: &2153142060 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: 0.7.1
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *2161137500
79
+ version_requirements: *2153142060
80
80
  description: ActiveRecord plugin designed to allow simple multiple table inheritance.
81
81
  email:
82
82
  - matt@matthuggins.com
@@ -87,6 +87,7 @@ extra_rdoc_files:
87
87
  files:
88
88
  - .gitignore
89
89
  - .rspec
90
+ - .travis.yml
90
91
  - CHANGELOG.md
91
92
  - Gemfile
92
93
  - README.md
@@ -94,13 +95,14 @@ files:
94
95
  - lib/multiple_table_inheritance.rb
95
96
  - lib/multiple_table_inheritance/child.rb
96
97
  - lib/multiple_table_inheritance/child/base.rb
98
+ - lib/multiple_table_inheritance/child/sanitizer.rb
97
99
  - lib/multiple_table_inheritance/migration.rb
98
100
  - lib/multiple_table_inheritance/parent.rb
99
101
  - lib/multiple_table_inheritance/parent/base.rb
100
102
  - lib/multiple_table_inheritance/parent/relation.rb
101
103
  - lib/multiple_table_inheritance/railtie.rb
102
104
  - lib/multiple_table_inheritance/version.rb
103
- - multiiple_table_inheritance.gemspec
105
+ - multiple_table_inheritance.gemspec
104
106
  - spec/active_record/child_spec.rb
105
107
  - spec/active_record/parent_spec.rb
106
108
  - spec/spec_helper.rb