has_many_polymorphic 0.5.0 → 0.6.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/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
|
-
==
|
9
|
+
== Setup
|
10
10
|
|
11
|
-
|
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
|
-
|
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
|
-
|
2
|
+
module HasManyPolymorphic #:nodoc:
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
def self.included(base)
|
5
|
+
base.extend(ClassMethods)
|
6
|
+
end
|
7
7
|
|
8
|
-
|
8
|
+
module ClassMethods
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
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
|
-
|
62
|
-
|
63
|
-
|
61
|
+
def has_many_polymorphic(name, options = {})
|
62
|
+
target_class_name = self.name
|
63
|
+
instance_array_name = "#{name}_array".to_sym
|
64
64
|
|
65
|
-
|
66
|
-
|
65
|
+
#declare array to related models
|
66
|
+
attr_accessor instance_array_name
|
67
67
|
|
68
|
-
|
69
|
-
|
68
|
+
#create the has_many relationship
|
69
|
+
has_many options[:through], :dependent => :destroy
|
70
70
|
|
71
|
-
|
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
|
-
|
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
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
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
|
-
|
94
|
-
|
93
|
+
#set it back to the instance variable
|
94
|
+
self.send("#{instance_array_name.to_s}=", records)
|
95
95
|
|
96
|
-
|
97
|
-
|
96
|
+
records
|
97
|
+
end
|
98
98
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
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
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
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
|
-
|
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
|
-
|
119
|
+
include RussellEdge::HasManyPolymorphic::InstanceMethods
|
120
120
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
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
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
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
|
-
|
141
|
+
|
142
|
+
end
|
143
|
+
end
|
data/lib/has_many_polymorphic.rb
CHANGED
@@ -1,7 +1,4 @@
|
|
1
1
|
require 'has_many_polymorphic/has_many_polymorphic'
|
2
|
-
|
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
|
-
|
5
|
-
prerelease:
|
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
|
-
|
19
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
67
|
-
|
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
|
-
|
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.
|
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
|