has_many_polymorphic 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -6,9 +6,10 @@ This mixin adds a has many polymorphic relationship to a model and creates all t
6
6
  - Models
7
7
  - the models you want to autoload so all the relationships are created on initialzation of Rails
8
8
 
9
- == Example Usage
9
+ == Setup
10
10
 
11
- RussellEdge::HasManyPolymorphic.options[:models] = %w(PreferenceType)
11
+ You must define the models that you want to use inside an initializer using
12
+ RussellEdge::HasManyPolymorphic.add_models(%w(PreferenceType)) or RussellEdge::HasManyPolymorphic.add_models("PreferenceType")
12
13
 
13
14
  == Params
14
15
  - Name
@@ -42,7 +43,7 @@ this gives you the following
42
43
 
43
44
  and
44
45
 
45
- preferenceType.preferenced_records
46
+ preferenceType.preferenced_records
46
47
 
47
48
  which is a concatentated array of the models. You also get the following
48
49
 
@@ -0,0 +1,44 @@
1
+ module RussellEdge
2
+ module HasManyPolymorphic
3
+ class Engine < Rails::Engine
4
+ isolate_namespace HasManyPolymorphic
5
+ DEFAULT_OPTIONS = {:models => %w()}
6
+ @@options = HashWithIndifferentAccess.new(DEFAULT_OPTIONS)
7
+
8
+ initializer "has_many_polymorphic.autoload_models", :after => :load_config_initializers do |app|
9
+ RussellEdge::HasManyPolymorphic::Engine.autoload_models
10
+ end
11
+
12
+ ActiveSupport.on_load(:active_record) do
13
+ include RussellEdge::HasManyPolymorphic
14
+ end
15
+
16
+ #set engine to scope
17
+ engine = self
18
+ config.to_prepare do
19
+ engine.autoload_models
20
+ end
21
+
22
+ class << self
23
+ def add_models(models)
24
+ if models.is_a? Array
25
+ @@options[:models] = @@options[:models] | models
26
+ else
27
+ @@options[:models] << models
28
+ end
29
+ end
30
+
31
+ # Dispatcher callback to load polymorphic relationships
32
+ def autoload_models
33
+ @@options[:models].each do |model|
34
+ #try to load model if it exists.
35
+ begin
36
+ model.constantize
37
+ rescue=>e
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,143 +1,143 @@
1
1
  module RussellEdge #:nodoc:
2
- module HasManyPolymorphic #:nodoc:
2
+ module HasManyPolymorphic #:nodoc:
3
3
 
4
- def self.included(base)
5
- base.extend(ClassMethods)
6
- end
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
7
7
 
8
- module ClassMethods
8
+ module ClassMethods
9
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
- ##
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
60
 
61
- def has_many_polymorphic(name, options = {})
62
- target_class_name = self.name
63
- instance_array_name = "#{name}_array".to_sym
61
+ def has_many_polymorphic(name, options = {})
62
+ target_class_name = self.name
63
+ instance_array_name = "#{name}_array".to_sym
64
64
 
65
- #declare array to related models
66
- attr_accessor instance_array_name
65
+ #declare array to related models
66
+ attr_accessor instance_array_name
67
67
 
68
- #create the has_many relationship
69
- has_many options[:through], :dependent => :destroy
68
+ #create the has_many relationship
69
+ has_many options[:through], :dependent => :destroy
70
70
 
71
- #create the has_many relationship for each model
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
72
79
  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
80
+ belongs_to model.to_s.singularize.to_sym, :class_name => model.to_s.classify, :foreign_key => "#{name.to_s.singularize}_id"
75
81
  end
82
+ end
76
83
 
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
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)
82
91
  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
92
 
93
- #set it back to the instance variable
94
- self.send("#{instance_array_name.to_s}=", records)
93
+ #set it back to the instance variable
94
+ self.send("#{instance_array_name.to_s}=", records)
95
95
 
96
- records
97
- end
96
+ records
97
+ end
98
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)
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
106
 
107
- if exisiting_record.nil?
108
- values_hash = {}
109
- values_hash["#{record.class.name.underscore}_id"] = record.id
110
- values_hash["#{name.to_s.singularize}_type"] = klass_name
111
- values_hash["#{name.to_s.singularize}_id"] = reln_record.id
107
+ if exisiting_record.nil?
108
+ values_hash = {}
109
+ values_hash["#{record.class.name.underscore}_id"] = record.id
110
+ values_hash["#{name.to_s.singularize}_type"] = klass_name
111
+ values_hash["#{name.to_s.singularize}_id"] = reln_record.id
112
112
 
113
- options[:through].to_s.classify.constantize.create(values_hash)
114
- end
113
+ options[:through].to_s.classify.constantize.create(values_hash)
115
114
  end
116
115
  end
116
+ end
117
117
 
118
118
  #include instance methods into this model
119
- include RussellEdge::HasManyPolymorphic::InstanceMethods
119
+ include RussellEdge::HasManyPolymorphic::InstanceMethods
120
120
 
121
- #add the relationship to the models.
122
- options[:models].each do |model|
123
- model.to_s.classify.constantize.class_exec do
124
- has_many options[:through], :as => name.to_s.singularize
125
- has_many target_class_name.tableize, :through => options[:through]
126
- end
121
+ #add the relationship to the models.
122
+ options[:models].each do |model|
123
+ model.to_s.classify.constantize.class_exec do
124
+ has_many options[:through], :as => name.to_s.singularize
125
+ has_many target_class_name.tableize, :through => options[:through]
127
126
  end
128
-
129
127
  end
128
+
130
129
  end
130
+ end
131
131
 
132
- module InstanceMethods
133
- #clear array on reload
134
- def reload(*args)
135
- @records = []
136
-
137
- super args
138
- end
132
+ module InstanceMethods
133
+ #clear array on reload
134
+ def reload(*args)
135
+ @records = []
139
136
 
137
+ super args
140
138
  end
141
139
 
142
140
  end
143
- end
141
+
142
+ end
143
+ end
@@ -1,3 +1,3 @@
1
1
  module HasManyPolymorphic
2
- VERSION = '0.5.0' unless defined?(::HasManyPolymorphic::VERSION)
2
+ VERSION = '0.6.0' unless defined?(::HasManyPolymorphic::VERSION)
3
3
  end
@@ -1,7 +1,4 @@
1
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'
2
+ require 'has_many_polymorphic/engine'
6
3
 
7
4
 
metadata CHANGED
@@ -1,87 +1,61 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: has_many_polymorphic
3
- version: !ruby/object:Gem::Version
4
- hash: 11
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 5
9
- - 0
10
- version: 0.5.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.0
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Russell Holmes
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-08-24 00:00:00 -04:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2011-11-15 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: activerecord
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &2152612200 !ruby/object:Gem::Requirement
25
17
  none: false
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 9
30
- segments:
31
- - 2
32
- - 3
33
- - 5
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
34
21
  version: 2.3.5
35
22
  type: :runtime
36
- version_requirements: *id001
23
+ prerelease: false
24
+ version_requirements: *2152612200
37
25
  description: Simple replacement for has_many_polymorphs
38
26
  email: rholmes@tnsolutionsinc.com
39
27
  executables: []
40
-
41
28
  extensions: []
42
-
43
29
  extra_rdoc_files: []
44
-
45
- files:
46
- - lib/has_many_polymorphic/autoload.rb
30
+ files:
31
+ - lib/has_many_polymorphic/engine.rb
47
32
  - lib/has_many_polymorphic/has_many_polymorphic.rb
48
33
  - lib/has_many_polymorphic/version.rb
49
34
  - lib/has_many_polymorphic.rb
50
35
  - MIT-LICENSE.txt
51
36
  - README.rdoc
52
- has_rdoc: true
53
37
  homepage: https://github.com/russ1985/has_many_polymorphic
54
38
  licenses: []
55
-
56
39
  post_install_message:
57
40
  rdoc_options: []
58
-
59
- require_paths:
41
+ require_paths:
60
42
  - lib
61
- required_ruby_version: !ruby/object:Gem::Requirement
43
+ required_ruby_version: !ruby/object:Gem::Requirement
62
44
  none: false
63
- requirements:
64
- - - ">="
65
- - !ruby/object:Gem::Version
66
- hash: 3
67
- segments:
68
- - 0
69
- version: "0"
70
- required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
50
  none: false
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- hash: 3
76
- segments:
77
- - 0
78
- version: "0"
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
79
55
  requirements: []
80
-
81
56
  rubyforge_project:
82
- rubygems_version: 1.3.7
57
+ rubygems_version: 1.8.10
83
58
  signing_key:
84
59
  specification_version: 3
85
60
  summary: Simple replacement for has_many_polymorphs
86
61
  test_files: []
87
-
@@ -1,37 +0,0 @@
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