polymorpheus 2.0.1 → 2.1.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.
- checksums.yaml +7 -0
- data/lib/polymorpheus.rb +11 -0
- data/lib/polymorpheus/interface.rb +3 -80
- data/lib/polymorpheus/interface/belongs_to_polymorphic.rb +43 -0
- data/lib/polymorpheus/interface/rails3/has_many_as_polymorph.rb +29 -0
- data/lib/polymorpheus/interface/rails4/has_many_as_polymorph.rb +32 -0
- data/lib/polymorpheus/interface/validates_polymorph.rb +15 -0
- data/lib/polymorpheus/version.rb +1 -1
- data/polymorpheus.gemspec +3 -3
- data/spec/mysql2_adapter_spec.rb +2 -2
- data/spec/support/class_defs.rb +6 -1
- metadata +31 -31
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 98f62a13d469e88f1edb1e1698d2898847d2a502
|
4
|
+
data.tar.gz: 5fc6c4393b389fb1484380869acd665486989c99
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cbc7cbdaa014f3dfe73be1259d7e3ccfe9be282891077a52223bd67ea6607025d2147e89122e26ca3760f64fd47312f6f69c1c0e34e5c3c66f3b05df33f0d82e
|
7
|
+
data.tar.gz: a857f954015d60c9ba09cbfee46370b3db654b23a32ef6ac7e2c518c42ec23ee7120c24065144aa3e8c7f6325f9d032e77793fd253508643aed9a78515a57dbc
|
data/lib/polymorpheus.rb
CHANGED
@@ -5,6 +5,17 @@ module Polymorpheus
|
|
5
5
|
autoload :Trigger, 'polymorpheus/trigger'
|
6
6
|
autoload :SchemaDumper, 'polymorpheus/schema_dumper'
|
7
7
|
|
8
|
+
module Interface
|
9
|
+
autoload :BelongsToPolymorphic, 'polymorpheus/interface/belongs_to_polymorphic'
|
10
|
+
autoload :ValidatesPolymorph, 'polymorpheus/interface/validates_polymorph'
|
11
|
+
|
12
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
13
|
+
autoload :HasManyAsPolymorph, 'polymorpheus/interface/rails4/has_many_as_polymorph'
|
14
|
+
else
|
15
|
+
autoload :HasManyAsPolymorph, 'polymorpheus/interface/rails3/has_many_as_polymorph'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
8
19
|
class InterfaceBuilder
|
9
20
|
autoload :Association, 'polymorpheus/interface_builder/association'
|
10
21
|
end
|
@@ -17,86 +17,9 @@ module Polymorpheus
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.included(base)
|
20
|
-
base.extend(
|
20
|
+
base.extend(BelongsToPolymorphic)
|
21
|
+
base.extend(HasManyAsPolymorph)
|
22
|
+
base.extend(ValidatesPolymorph)
|
21
23
|
end
|
22
|
-
|
23
|
-
module ClassMethods
|
24
|
-
|
25
|
-
def belongs_to_polymorphic(*association_names, options)
|
26
|
-
polymorphic_api = options[:as]
|
27
|
-
builder = Polymorpheus::InterfaceBuilder.new(polymorphic_api,
|
28
|
-
association_names)
|
29
|
-
|
30
|
-
# The POLYMORPHEUS_ASSOCIATIONS constant is useful for two reasons:
|
31
|
-
#
|
32
|
-
# 1. It is useful for other classes to be able to ask this class
|
33
|
-
# about its polymorphic relationship.
|
34
|
-
#
|
35
|
-
# 2. It prevents a class from defining multiple polymorphic
|
36
|
-
# relationships. Doing so would be a bad idea from a design
|
37
|
-
# standpoint, and we don't want to allow for (and support)
|
38
|
-
# that added complexity.
|
39
|
-
#
|
40
|
-
const_set('POLYMORPHEUS_ASSOCIATIONS', builder.association_names)
|
41
|
-
|
42
|
-
# Set belongs_to associations
|
43
|
-
builder.associations.each do |association|
|
44
|
-
belongs_to association.name.to_sym
|
45
|
-
end
|
46
|
-
|
47
|
-
# Exposed interface for introspection
|
48
|
-
define_method 'polymorpheus' do
|
49
|
-
builder.exposed_interface(self)
|
50
|
-
end
|
51
|
-
|
52
|
-
# Getter method
|
53
|
-
define_method polymorphic_api do
|
54
|
-
builder.get_associated_object(self)
|
55
|
-
end
|
56
|
-
|
57
|
-
# Setter method
|
58
|
-
define_method "#{polymorphic_api}=" do |object_to_associate|
|
59
|
-
builder.set_associated_object(self, object_to_associate)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def has_many_as_polymorph(association, options = {})
|
64
|
-
options.symbolize_keys!
|
65
|
-
conditions = options.fetch(:conditions, {})
|
66
|
-
fkey = name.foreign_key
|
67
|
-
|
68
|
-
class_name = options[:class_name] || association.to_s.classify
|
69
|
-
|
70
|
-
options[:conditions] = proc do
|
71
|
-
keys = class_name.constantize
|
72
|
-
.const_get('POLYMORPHEUS_ASSOCIATIONS')
|
73
|
-
.map(&:foreign_key)
|
74
|
-
keys.delete(fkey)
|
75
|
-
|
76
|
-
nil_columns = keys.reduce({}) { |hash, key| hash.merge!(key => nil) }
|
77
|
-
|
78
|
-
|
79
|
-
if self.is_a?(ActiveRecord::Associations::JoinDependency::JoinAssociation)
|
80
|
-
{ aliased_table_name => nil_columns }
|
81
|
-
else
|
82
|
-
{ association => nil_columns }
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
has_many association, options
|
87
|
-
end
|
88
|
-
|
89
|
-
def validates_polymorph(polymorphic_api)
|
90
|
-
validate Proc.new {
|
91
|
-
unless polymorpheus.active_association
|
92
|
-
association_names = polymorpheus.associations.map(&:name)
|
93
|
-
errors.add(:base, "You must specify exactly one of the following: "\
|
94
|
-
"{#{association_names.join(', ')}}")
|
95
|
-
end
|
96
|
-
}
|
97
|
-
end
|
98
|
-
|
99
|
-
end
|
100
|
-
|
101
24
|
end
|
102
25
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Polymorpheus
|
2
|
+
module Interface
|
3
|
+
module BelongsToPolymorphic
|
4
|
+
def belongs_to_polymorphic(*association_names, options)
|
5
|
+
polymorphic_api = options[:as]
|
6
|
+
builder = Polymorpheus::InterfaceBuilder.new(polymorphic_api,
|
7
|
+
association_names)
|
8
|
+
|
9
|
+
# The POLYMORPHEUS_ASSOCIATIONS constant is useful for two reasons:
|
10
|
+
#
|
11
|
+
# 1. It is useful for other classes to be able to ask this class
|
12
|
+
# about its polymorphic relationship.
|
13
|
+
#
|
14
|
+
# 2. It prevents a class from defining multiple polymorphic
|
15
|
+
# relationships. Doing so would be a bad idea from a design
|
16
|
+
# standpoint, and we don't want to allow for (and support)
|
17
|
+
# that added complexity.
|
18
|
+
#
|
19
|
+
const_set('POLYMORPHEUS_ASSOCIATIONS', builder.association_names)
|
20
|
+
|
21
|
+
# Set belongs_to associations
|
22
|
+
builder.associations.each do |association|
|
23
|
+
belongs_to association.name.to_sym
|
24
|
+
end
|
25
|
+
|
26
|
+
# Exposed interface for introspection
|
27
|
+
define_method 'polymorpheus' do
|
28
|
+
builder.exposed_interface(self)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Getter method
|
32
|
+
define_method polymorphic_api do
|
33
|
+
builder.get_associated_object(self)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Setter method
|
37
|
+
define_method "#{polymorphic_api}=" do |object_to_associate|
|
38
|
+
builder.set_associated_object(self, object_to_associate)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Polymorpheus
|
2
|
+
module Interface
|
3
|
+
module HasManyAsPolymorph
|
4
|
+
def has_many_as_polymorph(association, options = {})
|
5
|
+
options.symbolize_keys!
|
6
|
+
fkey = name.foreign_key
|
7
|
+
|
8
|
+
class_name = options[:class_name] || association.to_s.classify
|
9
|
+
|
10
|
+
options[:conditions] = proc do
|
11
|
+
keys = class_name.constantize
|
12
|
+
.const_get('POLYMORPHEUS_ASSOCIATIONS')
|
13
|
+
.map(&:foreign_key)
|
14
|
+
keys.delete(fkey)
|
15
|
+
|
16
|
+
nil_columns = keys.reduce({}) { |hash, key| hash.merge!(key => nil) }
|
17
|
+
|
18
|
+
if self.is_a?(ActiveRecord::Associations::JoinDependency::JoinAssociation)
|
19
|
+
{ aliased_table_name => nil_columns }
|
20
|
+
else
|
21
|
+
{ association => nil_columns }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
has_many association, options
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Polymorpheus
|
2
|
+
module Interface
|
3
|
+
module HasManyAsPolymorph
|
4
|
+
def has_many_as_polymorph(association, scope = nil, options = {})
|
5
|
+
if scope.instance_of?(Hash)
|
6
|
+
options = scope
|
7
|
+
scope = nil
|
8
|
+
end
|
9
|
+
|
10
|
+
options.symbolize_keys!
|
11
|
+
fkey = name.foreign_key
|
12
|
+
|
13
|
+
class_name = options[:class_name] || association.to_s.classify
|
14
|
+
|
15
|
+
conditions = proc do
|
16
|
+
keys = class_name.constantize
|
17
|
+
.const_get('POLYMORPHEUS_ASSOCIATIONS')
|
18
|
+
.map(&:foreign_key)
|
19
|
+
keys.delete(fkey)
|
20
|
+
|
21
|
+
nil_columns = keys.reduce({}) { |hash, key| hash.merge!(key => nil) }
|
22
|
+
|
23
|
+
relation = where(nil_columns)
|
24
|
+
relation = scope.call.merge(relation) unless scope.nil?
|
25
|
+
relation
|
26
|
+
end
|
27
|
+
|
28
|
+
has_many association, conditions, options
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Polymorpheus
|
2
|
+
module Interface
|
3
|
+
module ValidatesPolymorph
|
4
|
+
def validates_polymorph(polymorphic_api)
|
5
|
+
validate Proc.new {
|
6
|
+
unless polymorpheus.active_association
|
7
|
+
association_names = polymorpheus.associations.map(&:name)
|
8
|
+
errors.add(:base, "You must specify exactly one of the following: "\
|
9
|
+
"{#{association_names.join(', ')}}")
|
10
|
+
end
|
11
|
+
}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/polymorpheus/version.rb
CHANGED
data/polymorpheus.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.license = 'MIT'
|
19
19
|
|
20
20
|
s.add_dependency('foreigner')
|
21
|
-
s.add_dependency('activerecord', '>=3.0')
|
22
|
-
s.add_development_dependency('rspec-rails')
|
23
|
-
s.add_development_dependency('mysql2')
|
21
|
+
s.add_dependency('activerecord', '>= 3.2', '< 5.0')
|
22
|
+
s.add_development_dependency('rspec-rails', '~> 2.14.0')
|
23
|
+
s.add_development_dependency('mysql2', '~> 0.3')
|
24
24
|
end
|
data/spec/mysql2_adapter_spec.rb
CHANGED
@@ -107,8 +107,8 @@ describe Polymorpheus::ConnectionAdapters::MysqlAdapter do
|
|
107
107
|
end
|
108
108
|
|
109
109
|
describe "#triggers" do
|
110
|
-
let(:trigger1) {
|
111
|
-
let(:trigger2) {
|
110
|
+
let(:trigger1) { double(Trigger, :name => '1') }
|
111
|
+
let(:trigger2) { double(Trigger, :name => '2') }
|
112
112
|
|
113
113
|
before do
|
114
114
|
connection.stub_sql('show triggers', [:trigger1, :trigger2])
|
data/spec/support/class_defs.rb
CHANGED
@@ -9,7 +9,12 @@ end
|
|
9
9
|
|
10
10
|
# Hannibal Lecter is a villain, but not a supervillain
|
11
11
|
class Villain < ActiveRecord::Base
|
12
|
-
|
12
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
13
|
+
has_many_as_polymorph :story_arcs, -> { order('id DESC') }
|
14
|
+
else
|
15
|
+
has_many_as_polymorph :story_arcs, order: 'id DESC'
|
16
|
+
end
|
17
|
+
|
13
18
|
has_many :battles, through: :story_arcs
|
14
19
|
end
|
15
20
|
|
metadata
CHANGED
@@ -1,80 +1,77 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: polymorpheus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
5
|
-
prerelease:
|
4
|
+
version: 2.1.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Barun Singh
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-06-20 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: foreigner
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: activerecord
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
|
-
version: '3.
|
33
|
+
version: '3.2'
|
34
|
+
- - <
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '5.0'
|
38
37
|
type: :runtime
|
39
38
|
prerelease: false
|
40
39
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
40
|
requirements:
|
43
|
-
- -
|
41
|
+
- - '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '3.2'
|
44
|
+
- - <
|
44
45
|
- !ruby/object:Gem::Version
|
45
|
-
version: '
|
46
|
+
version: '5.0'
|
46
47
|
- !ruby/object:Gem::Dependency
|
47
48
|
name: rspec-rails
|
48
49
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
50
|
requirements:
|
51
|
-
- -
|
51
|
+
- - ~>
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
53
|
+
version: 2.14.0
|
54
54
|
type: :development
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
57
|
requirements:
|
59
|
-
- -
|
58
|
+
- - ~>
|
60
59
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
60
|
+
version: 2.14.0
|
62
61
|
- !ruby/object:Gem::Dependency
|
63
62
|
name: mysql2
|
64
63
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
64
|
requirements:
|
67
|
-
- -
|
65
|
+
- - ~>
|
68
66
|
- !ruby/object:Gem::Version
|
69
|
-
version: '0'
|
67
|
+
version: '0.3'
|
70
68
|
type: :development
|
71
69
|
prerelease: false
|
72
70
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
71
|
requirements:
|
75
|
-
- -
|
72
|
+
- - ~>
|
76
73
|
- !ruby/object:Gem::Version
|
77
|
-
version: '0'
|
74
|
+
version: '0.3'
|
78
75
|
description: Provides a database-friendly method for polymorphic relationships
|
79
76
|
email: bsingh@wegowise.com
|
80
77
|
executables: []
|
@@ -84,6 +81,10 @@ extra_rdoc_files:
|
|
84
81
|
- LICENSE.txt
|
85
82
|
files:
|
86
83
|
- lib/polymorpheus/adapter.rb
|
84
|
+
- lib/polymorpheus/interface/belongs_to_polymorphic.rb
|
85
|
+
- lib/polymorpheus/interface/rails3/has_many_as_polymorph.rb
|
86
|
+
- lib/polymorpheus/interface/rails4/has_many_as_polymorph.rb
|
87
|
+
- lib/polymorpheus/interface/validates_polymorph.rb
|
87
88
|
- lib/polymorpheus/interface.rb
|
88
89
|
- lib/polymorpheus/interface_builder/association.rb
|
89
90
|
- lib/polymorpheus/interface_builder.rb
|
@@ -111,26 +112,25 @@ files:
|
|
111
112
|
homepage: http://github.com/wegowise/polymorpheus
|
112
113
|
licenses:
|
113
114
|
- MIT
|
115
|
+
metadata: {}
|
114
116
|
post_install_message:
|
115
117
|
rdoc_options: []
|
116
118
|
require_paths:
|
117
119
|
- lib
|
118
120
|
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
-
none: false
|
120
121
|
requirements:
|
121
|
-
- -
|
122
|
+
- - '>='
|
122
123
|
- !ruby/object:Gem::Version
|
123
124
|
version: '0'
|
124
125
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
|
-
none: false
|
126
126
|
requirements:
|
127
|
-
- -
|
127
|
+
- - '>='
|
128
128
|
- !ruby/object:Gem::Version
|
129
129
|
version: 1.3.6
|
130
130
|
requirements: []
|
131
131
|
rubyforge_project:
|
132
|
-
rubygems_version:
|
132
|
+
rubygems_version: 2.0.14
|
133
133
|
signing_key:
|
134
|
-
specification_version:
|
134
|
+
specification_version: 4
|
135
135
|
summary: Provides a database-friendly method for polymorphic relationships
|
136
136
|
test_files: []
|