multiple_table_inheritance 0.1.7 → 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/CHANGELOG.md CHANGED
@@ -1,9 +1,19 @@
1
- 0.1.8
1
+ 0.1.10
2
2
 
3
3
  * Child model records can now inherit parent model methods via the :methods
4
4
  option when calling :inherits_from.
5
5
  * Added several unit tests.
6
6
 
7
+ 0.1.9
8
+
9
+ * Remove broken code accidentally included during testing.
10
+
11
+ 0.1.8
12
+
13
+ * Fix bug where rake commands cannot be run if `inherits_from` or
14
+ `acts_as_superclass` have been called within an ActiveRecord model and the
15
+ model's tables do not already exist.
16
+
7
17
  0.1.7
8
18
 
9
19
  * Fix bug caused by extraneous super call in sanitizer class.
data/README.md CHANGED
@@ -25,7 +25,7 @@ From the command line:
25
25
 
26
26
  From your Gemfile:
27
27
 
28
- gem 'multiple_table_inheritance', '~> 0.1.7'
28
+ gem 'multiple_table_inheritance', '~> 0.1.9'
29
29
 
30
30
  Usage
31
31
  =====
@@ -236,6 +236,9 @@ When inheriting from another parent model, methods can optionally be called on
236
236
  the parent model automatically as well. To do so, specify the `:methods`
237
237
  option when calling `inherits_from`.
238
238
 
239
+ NOTE: This is not fully implemented yet as of version 0.1.9. Please wait until
240
+ a future release to prior to using this feature.
241
+
239
242
  class Employee < ActiveRecord::Base
240
243
  acts_as_superclass
241
244
  belongs_to :team
@@ -253,6 +256,3 @@ option when calling `inherits_from`.
253
256
  @programmer = Programmer.first
254
257
  @programmer.give_raise!
255
258
  # yields: "Congrats on your well-deserved raise, Mike!"
256
-
257
- NOTE: This is not fully implemented yet as of version 0.1.7. Please wait until
258
- a future release to prior to using this feature.
@@ -16,7 +16,9 @@ module MultipleTableInheritance
16
16
  options = Base::default_options.merge(options.to_options)
17
17
  inherit_methods = options.delete(:methods)
18
18
 
19
- extend FinderMethods, SharedMethods
19
+ @inherited_attribute_methods_mutex = Mutex.new
20
+
21
+ extend AttributeMethods, FinderMethods, SharedMethods
20
22
  include InstanceMethods, SharedMethods
21
23
  include DelegateMethods if inherit_methods
22
24
 
@@ -29,41 +31,31 @@ module MultipleTableInheritance
29
31
  send("#{parent_association_name}_without_autobuild") || send("build_#{parent_association_name}")
30
32
  end
31
33
 
32
- # Allow getting and setting of parent attributes and relationships.
33
- inherited_columns_and_associations.each do |name|
34
- delegate name, "#{name}=", :to => parent_association_name
35
- end
36
-
37
- # Ensure parent's accessible attributes are accessible in child.
38
- parent_association_class.accessible_attributes.each do |attr|
39
- attr_accessible attr.to_sym
40
- end
41
-
42
34
  # Bind relationship, handle validation, and save properly.
43
35
  belongs_to parent_association_name, options
44
36
  alias_method_chain parent_association_name, :autobuild
45
37
  before_validation :set_association_subtype
46
38
  validate :parent_association_must_be_valid
47
39
  before_save :parent_association_must_be_saved
40
+
41
+ # denote that the association methods have not been built
42
+ @loaded = false
48
43
  end
49
44
 
50
45
  def parent_association_class
51
- reflection = create_reflection(:belongs_to, parent_association_name, {}, self)
52
- reflection.klass
46
+ @parent_association_class ||= begin
47
+ reflection = create_reflection(:belongs_to, parent_association_name, {}, self)
48
+ reflection.klass
49
+ end
53
50
  end
54
51
 
55
52
  private
56
53
 
57
54
  def inherited_columns_and_associations
58
55
  # Get the associated columns and relationship names
59
- inherited_columns = parent_association_class.column_names
56
+ inherited_columns = parent_association_class.column_names - column_names
60
57
  inherited_methods = parent_association_class.reflections.map { |key, value| key.to_s }
61
58
 
62
- # Filter out columns that the class already has
63
- # inherited_columns = inherited_columns.reject do |column|
64
- # (self.column_names.grep(column).length > 0) || (column == 'type') || (column == parent_association_class.subtype_column)
65
- # end
66
-
67
59
  # Filter out methods that the class already has
68
60
  inherited_methods = inherited_methods.reject do |method|
69
61
  self.reflections.map { |key, value| key.to_s }.include?(method)
@@ -73,13 +65,49 @@ module MultipleTableInheritance
73
65
  end
74
66
  end
75
67
 
68
+ module AttributeMethods
69
+ def define_attribute_methods
70
+ super
71
+
72
+ @inherited_attribute_methods_mutex.synchronize do
73
+ return if inherited_attribute_methods_generated?
74
+ inherit_parent_attributes
75
+ inherit_parent_accessible_attributes
76
+ inherited_attribute_methods_generated!
77
+ end
78
+ end
79
+
80
+ def inherit_parent_attributes
81
+ inherited_columns_and_associations.each do |name|
82
+ delegate name, "#{name}=", :to => parent_association_name
83
+ end
84
+ end
85
+
86
+ def inherit_parent_accessible_attributes
87
+ parent_association_class.accessible_attributes.each do |attr|
88
+ attr_accessible attr.to_sym
89
+ end
90
+ end
91
+
92
+ def inherited_attribute_methods_generated?
93
+ @inherited_attribute_methods_generated ||= false
94
+ end
95
+
96
+ def inherited_attribute_methods_generated!
97
+ @inherited_attribute_methods_generated = true
98
+ end
99
+ end
100
+
76
101
  module FinderMethods
77
102
  def find_by_sql(*args)
78
103
  child_records = super(*args)
79
104
 
105
+ ids = child_records.collect(&:id)
106
+ parent_records = parent_association_class.as_supertype.find_all_by_id(ids)
107
+
80
108
  child_records.each do |child|
81
- parent = parent_association_class.as_supertype.find_by_id(child.id)
82
- child.send(:parent_association=, parent)
109
+ parent = parent_records.find { |parent| parent.id == child.id }
110
+ child.send(:parent_association=, parent) if parent
83
111
  end
84
112
  end
85
113
  end
@@ -17,11 +17,36 @@ module MultipleTableInheritance
17
17
  options = Base::default_options.merge(options.to_options)
18
18
  self.subtype_column = options[:subtype]
19
19
 
20
+ @child_attribute_methods_mutex = Mutex.new
21
+ extend AttributeMethods
22
+ end
23
+ end
24
+
25
+ module AttributeMethods
26
+ def define_attribute_methods
27
+ super
28
+
29
+ @child_attribute_methods_mutex.synchronize do
30
+ return if child_attribute_methods_generated?
31
+ extend_child_association
32
+ child_attribute_methods_generated!
33
+ end
34
+ end
35
+
36
+ def extend_child_association
20
37
  if column_names.include?(subtype_column.to_s)
21
38
  include InstanceMethods
22
39
  before_destroy :destroy_child_association
23
40
  end
24
41
  end
42
+
43
+ def child_attribute_methods_generated?
44
+ @child_attribute_methods_generated ||= false
45
+ end
46
+
47
+ def child_attribute_methods_generated!
48
+ @child_attribute_methods_generated = true
49
+ end
25
50
  end
26
51
 
27
52
  module InstanceMethods
@@ -1,3 +1,3 @@
1
1
  module MultipleTableInheritance
2
- VERSION = "0.1.7"
2
+ VERSION = "0.1.9"
3
3
  end
data/spec/spec_helper.rb CHANGED
@@ -4,8 +4,9 @@ require 'multiple_table_inheritance'
4
4
 
5
5
  MultipleTableInheritance::Railtie.insert
6
6
 
7
- require 'support/tables'
7
+ require 'support/database'
8
8
  require 'support/models'
9
+ require 'support/tables'
9
10
 
10
11
  module MultipleTableInheritanceSpecHelper
11
12
  def mock_employees!
@@ -0,0 +1,10 @@
1
+ db_path = File.expand_path(File.join(File.dirname(__FILE__), '../../db'))
2
+ db_file = File.join(db_path, 'multiple_table_inheritance.db')
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)
@@ -1,13 +1,3 @@
1
- db_path = File.expand_path(File.join(File.dirname(__FILE__), '../../db'))
2
- db_file = File.join(db_path, 'multiple_table_inheritance.db')
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)
11
1
  conn = ActiveRecord::Base.connection
12
2
 
13
3
  #########################################################
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.7
4
+ version: 0.1.9
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-16 00:00:00.000000000Z
12
+ date: 2012-03-24 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
16
- requirement: &2153035620 !ruby/object:Gem::Requirement
16
+ requirement: &2156229580 !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: *2153035620
24
+ version_requirements: *2156229580
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: activesupport
27
- requirement: &2153035040 !ruby/object:Gem::Requirement
27
+ requirement: &2156229000 !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: *2153035040
35
+ version_requirements: *2156229000
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec-rails
38
- requirement: &2153034460 !ruby/object:Gem::Requirement
38
+ requirement: &2156228420 !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: *2153034460
46
+ version_requirements: *2156228420
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec_tag_matchers
49
- requirement: &2153033940 !ruby/object:Gem::Requirement
49
+ requirement: &2156227840 !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: *2153033940
57
+ version_requirements: *2156227840
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: sqlite3-ruby
60
- requirement: &2153033420 !ruby/object:Gem::Requirement
60
+ requirement: &2156227260 !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: *2153033420
68
+ version_requirements: *2156227260
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: database_cleaner
71
- requirement: &2153032860 !ruby/object:Gem::Requirement
71
+ requirement: &2156226680 !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: *2153032860
79
+ version_requirements: *2156226680
80
80
  description: ActiveRecord plugin designed to allow simple multiple table inheritance.
81
81
  email:
82
82
  - matt@matthuggins.com
@@ -106,6 +106,7 @@ files:
106
106
  - spec/active_record/child_spec.rb
107
107
  - spec/active_record/parent_spec.rb
108
108
  - spec/spec_helper.rb
109
+ - spec/support/database.rb
109
110
  - spec/support/models.rb
110
111
  - spec/support/tables.rb
111
112
  homepage: http://github.com/mhuggins/multiple_table_inheritance
@@ -137,5 +138,6 @@ test_files:
137
138
  - spec/active_record/child_spec.rb
138
139
  - spec/active_record/parent_spec.rb
139
140
  - spec/spec_helper.rb
141
+ - spec/support/database.rb
140
142
  - spec/support/models.rb
141
143
  - spec/support/tables.rb