has_many_polymorphic 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,20 +1,20 @@
1
- Copyright (c) 2007-2011 Collective Idea
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
1
+ Copyright (c) 2007-2011 Collective Idea
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,53 +1,53 @@
1
- = HasManyPolymorphic
2
-
3
- This mixin adds a has many polymorphic relationship to a model and creates all the relationships needed by rails to handle it.
4
-
5
- == Options
6
- - Models
7
- - the models you want to autoload so all the relationships are created on initialzation of Rails
8
-
9
- == Example Usage
10
-
11
- RussellEdge::HasManyPolymorphic.options[:models] = %w(PreferenceType)
12
-
13
- == Params
14
- - Name
15
- - name of the relationship, there is a convention that whatever name you choose, the polymorphic table columns on your through table should match.
16
-
17
- - Options
18
- - through - the model that handles the through relationship
19
- - models - models that should be included in this polymophic relationship
20
-
21
-
22
- == Added methods
23
-
24
- - {name param}
25
- - the name of your relationship is used for the method name of this method. it will return an array of the models that are related via the has_many relationships
26
-
27
- There is an after_save call back that will save the relationships when they are added or removed. If you want to remove a relationship the models need to be destroyed and this model reloaded.
28
-
29
- == Example Usage
30
-
31
- class PreferenceType < ActiveRecord::Base
32
- has_many_polymorphic :preferenced_records,
33
- :through => :valid_preference_types,
34
- :models => [:desktops, :organizers]
35
- end
36
-
37
- this gives you the following
38
-
39
- preferenceType = PreferenceType.first
40
- preferenceType.desktops
41
- preferenceType.organizers
42
-
43
- and
44
-
45
- preferenceType.preferenced_records
46
-
47
- which is a concatentated array of the models. You also get the following
48
-
49
- desktop = Desktop.first
50
- desktop.preference_types
51
-
52
- organizer = Organizer.first
1
+ = HasManyPolymorphic
2
+
3
+ This mixin adds a has many polymorphic relationship to a model and creates all the relationships needed by rails to handle it.
4
+
5
+ == Options
6
+ - Models
7
+ - the models you want to autoload so all the relationships are created on initialzation of Rails
8
+
9
+ == Example Usage
10
+
11
+ RussellEdge::HasManyPolymorphic.options[:models] = %w(PreferenceType)
12
+
13
+ == Params
14
+ - Name
15
+ - name of the relationship, there is a convention that whatever name you choose, the polymorphic table columns on your through table should match.
16
+
17
+ - Options
18
+ - through - the model that handles the through relationship
19
+ - models - models that should be included in this polymophic relationship
20
+
21
+
22
+ == Added methods
23
+
24
+ - {name param}
25
+ - the name of your relationship is used for the method name of this method. it will return an array of the models that are related via the has_many relationships
26
+
27
+ There is an after_save call back that will save the relationships when they are added or removed. If you want to remove a relationship the models need to be destroyed and this model reloaded.
28
+
29
+ == Example Usage
30
+
31
+ class PreferenceType < ActiveRecord::Base
32
+ has_many_polymorphic :preferenced_records,
33
+ :through => :valid_preference_types,
34
+ :models => [:desktops, :organizers]
35
+ end
36
+
37
+ this gives you the following
38
+
39
+ preferenceType = PreferenceType.first
40
+ preferenceType.desktops
41
+ preferenceType.organizers
42
+
43
+ and
44
+
45
+ preferenceType.preferenced_records
46
+
47
+ which is a concatentated array of the models. You also get the following
48
+
49
+ desktop = Desktop.first
50
+ desktop.preference_types
51
+
52
+ organizer = Organizer.first
53
53
  organizer.preference_types
@@ -1,7 +1,7 @@
1
- require 'has_many_polymorphic/has_many_polymorphic'
2
- ActiveRecord::Base.send :include, RussellEdge::HasManyPolymorphic
3
-
4
- #used to tie into Rails initialization to load the models so the relationships are created
5
- require 'has_many_polymorphic/autoload'
6
-
7
-
1
+ require 'has_many_polymorphic/has_many_polymorphic'
2
+ ActiveRecord::Base.send :include, RussellEdge::HasManyPolymorphic
3
+
4
+ #used to tie into Rails initialization to load the models so the relationships are created
5
+ require 'has_many_polymorphic/autoload'
6
+
7
+
@@ -1,37 +1,37 @@
1
- module RussellEdge
2
- module HasManyPolymorphic
3
-
4
- =begin rdoc
5
- Searches for models that use <tt>has_many_polymorphic</tt> and makes sure that they get loaded during app initialization.
6
- This ensures that helper methods are injected into the target classes.
7
- =end
8
-
9
- #define the models that use has_many_polymorphic. has_many_polymorphs combed the file system for models
10
- #that had the has_many_polymorphs method. This is not as robust but more efficent. It can be set via
11
- #
12
- #RussellEdge::HasManyPolymorphic::OPTIONS = { :models => %w(PreferenceType AnotherModel) }
13
- #
14
- DEFAULT_OPTIONS = {:models => %w()}
15
- mattr_accessor :options
16
- @@options = HashWithIndifferentAccess.new(DEFAULT_OPTIONS)
17
-
18
- # Dispatcher callback to load polymorphic relationships
19
- def self.autoload
20
- options[:models].each do |model|
21
- #try to load model if it exists.
22
- begin
23
- model.constantize
24
- rescue=>e
25
- end
26
- end
27
-
28
- end
29
- end
30
- end
31
-
32
- #create Railtie to plugin into rails initialization
33
- class RussellEdge::HasManyPolymorphic::RailTie < Rails::Railtie
34
- initializer "has_many_polymorphic.autoload_models", :after => :initialize do |app|
35
- RussellEdge::HasManyPolymorphic.autoload
36
- end
37
- end
1
+ module RussellEdge
2
+ module HasManyPolymorphic
3
+
4
+ =begin rdoc
5
+ Searches for models that use <tt>has_many_polymorphic</tt> and makes sure that they get loaded during app initialization.
6
+ This ensures that helper methods are injected into the target classes.
7
+ =end
8
+
9
+ #define the models that use has_many_polymorphic. has_many_polymorphs combed the file system for models
10
+ #that had the has_many_polymorphs method. This is not as robust but more efficent. It can be set via
11
+ #
12
+ #RussellEdge::HasManyPolymorphic::OPTIONS = { :models => %w(PreferenceType AnotherModel) }
13
+ #
14
+ DEFAULT_OPTIONS = {:models => %w()}
15
+ mattr_accessor :options
16
+ @@options = HashWithIndifferentAccess.new(DEFAULT_OPTIONS)
17
+
18
+ # Dispatcher callback to load polymorphic relationships
19
+ def self.autoload
20
+ options[:models].each do |model|
21
+ #try to load model if it exists.
22
+ begin
23
+ model.constantize
24
+ rescue=>e
25
+ end
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+
32
+ #create Railtie to plugin into rails initialization
33
+ class RussellEdge::HasManyPolymorphic::RailTie < Rails::Railtie
34
+ initializer "has_many_polymorphic.autoload_models", :after => :initialize do |app|
35
+ RussellEdge::HasManyPolymorphic.autoload
36
+ end
37
+ end
@@ -1,144 +1,144 @@
1
- module RussellEdge #:nodoc:
2
- module HasManyPolymorphic #:nodoc:
3
-
4
- def self.included(base)
5
- base.extend(ClassMethods)
6
- end
7
-
8
- module ClassMethods
9
-
10
- ##
11
- # HasManyPolymorphic
12
- # This mixin adds a has many polymorphic relationship to a model and creates all the relationships needed
13
- # by rails to handle it.
14
- #
15
- # Params
16
- #
17
- # Name - name of the relationship, there is a convention that whatever name you choose, the polymorphic
18
- # table columns on your through table should match.
19
- #
20
- # Options
21
- # - through - the model that handles the through relationship
22
- # - models - models that should be included in this polymophic relationship
23
- #
24
- #
25
- # One method is added for you to use
26
- #
27
- # - {name param}
28
- # - the name of your relationship is used for the method name of this method. it will return
29
- # an array of the models that are related via the has_many relationships
30
- #
31
- # There is an after_save call back that will save the relationships when they are added or removed
32
- # If you want to remove a relationship the models need to be destroyed and this model reloaded.
33
- #
34
- # Example Usage
35
- #
36
- # class PreferenceType < ActiveRecord::Base
37
- # has_morpheus :preferenced_records,
38
- # :through => :valid_preference_types,
39
- # :models => [:desktops, :organizers]
40
- # end
41
- #
42
- # this gives you the following
43
- #
44
- # preferenceType = PreferenceType.first
45
- # preferenceType.desktops
46
- # preferenceType.organizers
47
- #
48
- # and
49
- #
50
- # preferenceType.preferenced_records
51
- #
52
- # which is a concatentated array of the models. You also get the following
53
- #
54
- # desktop = Desktop.first
55
- # desktop.preference_types
56
- #
57
- # organizer = Organizer.first
58
- # organizer.preference_types
59
- ##
60
-
61
- def has_many_polymorphic(name, options = {})
62
- target_class_name = self.name
63
- instance_array_name = "#{name}_array".to_sym
64
-
65
- #declare array to related models
66
- attr_accessor instance_array_name
67
-
68
- #create the has_many relationship
69
- has_many options[:through], :dependent => :destroy
70
-
71
- #create the has_many relationship for each model
72
- options[:models].each do |model|
73
- has_many model, :through => options[:through], :source => model.to_s.singularize,
74
- :conditions => ["#{options[:through]}.#{name.to_s.singularize}_type = ?", model.to_s.classify], :dependent => :destroy
75
- end
76
-
77
- #modify the through class to add the belongs to relationships
78
- options[:through].to_s.classify.constantize.class_exec do
79
- options[:models].each do |model|
80
- belongs_to model.to_s.singularize.to_sym, :class_name => model.to_s.classify, :foreign_key => "#{name.to_s.singularize}_id"
81
- end
82
- end
83
-
84
- #I want to keep the << and push methods of array so this helps to keep them.
85
- define_method name do
86
- #used the declared instance variable array
87
- records = self.send(instance_array_name.to_s)
88
- records = records || []
89
- options[:models].each do |model|
90
- records = records | self.send(model.to_s)
91
- end
92
-
93
- #set it back to the instance variable
94
- self.send("#{instance_array_name.to_s}=", records)
95
-
96
- records
97
- end
98
-
99
- #before we save this model make sure you save all the relationships.
100
- before_save do |record|
101
- record.send(name).each do |reln_record|
102
- conditions = "#{name.to_s.singularize}_id = #{reln_record.id} and #{name.to_s.singularize}_type = '#{reln_record.class.name}'"
103
- exisiting_record = record.send("#{options[:through]}").find(:first,
104
- :conditions => conditions)
105
-
106
- #handle STI get superclass class_name if not sub class of ActiveRecord::Base
107
- class_name = (reln_record.superclass == ActiveRecord::Base) ? reln_record.class.name : reln_record.superclass.class.name
108
- if exisiting_record.nil?
109
- values_hash = {}
110
- values_hash["#{record.class.name.underscore}_id"] = record.id
111
- values_hash["#{name.to_s.singularize}_type"] = reln_record.class.name
112
- values_hash["#{name.to_s.singularize}_id"] = reln_record.id
113
-
114
- options[:through].to_s.classify.constantize.create(values_hash)
115
- end
116
- end
117
- end
118
-
119
- #include instance methods into this model
120
- include RussellEdge::HasManyPolymorphic::InstanceMethods
121
-
122
- #add the relationship to the models.
123
- options[:models].each do |model|
124
- model.to_s.classify.constantize.class_exec do
125
- has_many options[:through], :as => name.to_s.singularize
126
- has_many target_class_name.tableize, :through => options[:through]
127
- end
128
- end
129
-
130
- end
131
- end
132
-
133
- module InstanceMethods
134
- #clear array on reload
135
- def reload(*args)
136
- @records = []
137
-
138
- super args
139
- end
140
-
141
- end
142
-
143
- end
1
+ module RussellEdge #:nodoc:
2
+ module HasManyPolymorphic #:nodoc:
3
+
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
7
+
8
+ module ClassMethods
9
+
10
+ ##
11
+ # HasManyPolymorphic
12
+ # This mixin adds a has many polymorphic relationship to a model and creates all the relationships needed
13
+ # by rails to handle it.
14
+ #
15
+ # Params
16
+ #
17
+ # Name - name of the relationship, there is a convention that whatever name you choose, the polymorphic
18
+ # table columns on your through table should match.
19
+ #
20
+ # Options
21
+ # - through - the model that handles the through relationship
22
+ # - models - models that should be included in this polymophic relationship
23
+ #
24
+ #
25
+ # One method is added for you to use
26
+ #
27
+ # - {name param}
28
+ # - the name of your relationship is used for the method name of this method. it will return
29
+ # an array of the models that are related via the has_many relationships
30
+ #
31
+ # There is an after_save call back that will save the relationships when they are added or removed
32
+ # If you want to remove a relationship the models need to be destroyed and this model reloaded.
33
+ #
34
+ # Example Usage
35
+ #
36
+ # class PreferenceType < ActiveRecord::Base
37
+ # has_morpheus :preferenced_records,
38
+ # :through => :valid_preference_types,
39
+ # :models => [:desktops, :organizers]
40
+ # end
41
+ #
42
+ # this gives you the following
43
+ #
44
+ # preferenceType = PreferenceType.first
45
+ # preferenceType.desktops
46
+ # preferenceType.organizers
47
+ #
48
+ # and
49
+ #
50
+ # preferenceType.preferenced_records
51
+ #
52
+ # which is a concatentated array of the models. You also get the following
53
+ #
54
+ # desktop = Desktop.first
55
+ # desktop.preference_types
56
+ #
57
+ # organizer = Organizer.first
58
+ # organizer.preference_types
59
+ ##
60
+
61
+ def has_many_polymorphic(name, options = {})
62
+ target_class_name = self.name
63
+ instance_array_name = "#{name}_array".to_sym
64
+
65
+ #declare array to related models
66
+ attr_accessor instance_array_name
67
+
68
+ #create the has_many relationship
69
+ has_many options[:through], :dependent => :destroy
70
+
71
+ #create the has_many relationship for each model
72
+ options[:models].each do |model|
73
+ has_many model, :through => options[:through], :source => model.to_s.singularize,
74
+ :conditions => ["#{options[:through]}.#{name.to_s.singularize}_type = ?", model.to_s.classify], :dependent => :destroy
75
+ end
76
+
77
+ #modify the through class to add the belongs to relationships
78
+ options[:through].to_s.classify.constantize.class_exec do
79
+ options[:models].each do |model|
80
+ belongs_to model.to_s.singularize.to_sym, :class_name => model.to_s.classify, :foreign_key => "#{name.to_s.singularize}_id"
81
+ end
82
+ end
83
+
84
+ #I want to keep the << and push methods of array so this helps to keep them.
85
+ define_method name do
86
+ #used the declared instance variable array
87
+ records = self.send(instance_array_name.to_s)
88
+ records = records || []
89
+ options[:models].each do |model|
90
+ records = records | self.send(model.to_s)
91
+ end
92
+
93
+ #set it back to the instance variable
94
+ self.send("#{instance_array_name.to_s}=", records)
95
+
96
+ records
97
+ end
98
+
99
+ #before we save this model make sure you save all the relationships.
100
+ before_save do |record|
101
+ record.send(name).each do |reln_record|
102
+ #handle STI get superclass class_name if not sub class of ActiveRecord::Base
103
+ klass_name = (reln_record.class.superclass == ActiveRecord::Base) ? reln_record.class.name : reln_record.class.superclass.name
104
+ conditions = "#{name.to_s.singularize}_id = #{reln_record.id} and #{name.to_s.singularize}_type = '#{klass_name}'"
105
+ exisiting_record = record.send("#{options[:through]}").find(:first,:conditions => conditions)
106
+
107
+ if exisiting_record.nil?
108
+ class_name = (reln_record.class.superclass == ActiveRecord::Base) ? reln_record.class.name : reln_record.class.superclass.name
109
+ values_hash = {}
110
+ values_hash["#{record.class.name.underscore}_id"] = record.id
111
+ values_hash["#{name.to_s.singularize}_type"] = klass_name
112
+ values_hash["#{name.to_s.singularize}_id"] = reln_record.id
113
+
114
+ options[:through].to_s.classify.constantize.create(values_hash)
115
+ end
116
+ end
117
+ end
118
+
119
+ #include instance methods into this model
120
+ include RussellEdge::HasManyPolymorphic::InstanceMethods
121
+
122
+ #add the relationship to the models.
123
+ options[:models].each do |model|
124
+ model.to_s.classify.constantize.class_exec do
125
+ has_many options[:through], :as => name.to_s.singularize
126
+ has_many target_class_name.tableize, :through => options[:through]
127
+ end
128
+ end
129
+
130
+ end
131
+ end
132
+
133
+ module InstanceMethods
134
+ #clear array on reload
135
+ def reload(*args)
136
+ @records = []
137
+
138
+ super args
139
+ end
140
+
141
+ end
142
+
143
+ end
144
144
  end
@@ -1,3 +1,3 @@
1
- module HasManyPolymorphic
2
- VERSION = '0.3.0' unless defined?(::HasManyPolymorphic::VERSION)
1
+ module HasManyPolymorphic
2
+ VERSION = '0.4.0' unless defined?(::HasManyPolymorphic::VERSION)
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: has_many_polymorphic
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
5
- prerelease:
4
+ hash: 15
5
+ prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 3
8
+ - 4
9
9
  - 0
10
- version: 0.3.0
10
+ version: 0.4.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Russell Holmes
@@ -15,7 +15,8 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-08-24 00:00:00 Z
18
+ date: 2011-08-24 00:00:00 -04:00
19
+ default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: activerecord
@@ -48,6 +49,7 @@ files:
48
49
  - lib/has_many_polymorphic.rb
49
50
  - MIT-LICENSE.txt
50
51
  - README.rdoc
52
+ has_rdoc: true
51
53
  homepage: https://github.com/russ1985/has_many_polymorphic
52
54
  licenses: []
53
55
 
@@ -77,7 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
77
79
  requirements: []
78
80
 
79
81
  rubyforge_project:
80
- rubygems_version: 1.8.6
82
+ rubygems_version: 1.3.7
81
83
  signing_key:
82
84
  specification_version: 3
83
85
  summary: Simple replacement for has_many_polymorphs