active_poro 0.0.4 → 0.0.5
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 +4 -4
- data/.ruby-version +2 -1
- data/README.md +3 -5
- data/active_poro.gemspec +2 -0
- data/lib/active_poro/relations.rb +30 -29
- data/lib/active_poro/version.rb +1 -1
- data/spec/active_poro_spec.rb +25 -4
- data/spec/spec_helper.rb +15 -0
- data/spec/support/base_test_class.rb +2 -7
- metadata +31 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 657deddc2134e4fcaaa62c9fbe84bece78e613bd
|
4
|
+
data.tar.gz: 0268c80ce1c30a2462997463b86e94d64bd0b03b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 02c15b6276f732edba9595b531f9640802d6a994e21ca64e947fd15993a67fb9010c1f5163639bc888b489f3cba76a4e8ae9e0e38082a6c2be17091a114a09eb
|
7
|
+
data.tar.gz: 6ed9ae1f95d3be32edea5df94da58011f89e039a61ff900b79488275b0a51d9fcc83841d2e7dcf53efd35a0c68e7aaa8e3b8b19affc077e1e49432c8eb53b300
|
data/.ruby-version
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
2.0.0-
|
1
|
+
2.0.0-p451
|
2
|
+
|
data/README.md
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
# active_poro
|
2
|
-
Makes possible the use of has_many, has_one, belongs_to relations in POROs as you would expect
|
3
|
-
|
4
|
-
Important!
|
5
|
-
----------
|
6
2
|
|
7
|
-
|
3
|
+
[](http://badge.fury.io/rb/active_poro)
|
4
|
+
[](https://codeclimate.com/github/codescrum/active_poro)
|
8
5
|
|
6
|
+
Makes possible the use of has_many, has_one, belongs_to relations in POROs as you would expect
|
9
7
|
|
10
8
|
## Installation
|
11
9
|
|
data/active_poro.gemspec
CHANGED
@@ -22,6 +22,8 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_development_dependency "rake", "~> 10.0"
|
23
23
|
spec.add_development_dependency('rspec')
|
24
24
|
spec.add_development_dependency('jazz_hands')
|
25
|
+
spec.add_development_dependency('simplecov', '0.9.0')
|
26
|
+
spec.add_development_dependency('codeclimate-test-reporter', '0.4.0')
|
25
27
|
|
26
28
|
spec.add_runtime_dependency('activesupport')
|
27
29
|
end
|
@@ -4,6 +4,7 @@ module ActivePoro
|
|
4
4
|
|
5
5
|
module ClassMethods
|
6
6
|
def has_many(target_name)
|
7
|
+
|
7
8
|
# define getter method
|
8
9
|
define_method target_name do
|
9
10
|
instance_variable_get("@#{target_name}") || []
|
@@ -17,12 +18,12 @@ module ActivePoro
|
|
17
18
|
|
18
19
|
# set the instance variable only if I am now the rightful owner
|
19
20
|
instance_variable_set("@#{target_name}", members)
|
20
|
-
|
21
|
+
singular_reflection_name = self.class.name.underscore
|
21
22
|
members.each do |member|
|
22
23
|
|
23
|
-
current_owner = member.send(
|
24
|
+
current_owner = member.send(singular_reflection_name)
|
24
25
|
if current_owner.nil? # no current assignment
|
25
|
-
member.send "#{
|
26
|
+
member.send "#{singular_reflection_name}=", self
|
26
27
|
elsif current_owner != self # current assignment is not me
|
27
28
|
other_members = current_owner.send target_name
|
28
29
|
if other_members.include?(member)
|
@@ -33,7 +34,7 @@ module ActivePoro
|
|
33
34
|
raise "Unmatching association; Current owner (#{current_owner.class.name}) of #{member.class.name} does not have it as a member"
|
34
35
|
end
|
35
36
|
# add me as associated to the member I am also including
|
36
|
-
member.send "#{
|
37
|
+
member.send "#{singular_reflection_name}=", self
|
37
38
|
else
|
38
39
|
# its already me, do not do anything
|
39
40
|
end
|
@@ -41,13 +42,16 @@ module ActivePoro
|
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
45
|
+
# the singular suffix for add and remove methods
|
46
|
+
singular_target_name = target_name.to_s.singularize
|
47
|
+
|
44
48
|
# define the "add_<name>" method
|
45
|
-
define_method "add_#{
|
49
|
+
define_method "add_#{singular_target_name}" do |member|
|
46
50
|
send("#{target_name}=", (send(target_name) + [member]).uniq)
|
47
51
|
end
|
48
52
|
|
49
53
|
# define the "remove_<name>" method
|
50
|
-
define_method "remove_#{
|
54
|
+
define_method "remove_#{singular_target_name}" do |member|
|
51
55
|
send("#{target_name}=", (send(target_name) - [member]).uniq)
|
52
56
|
end
|
53
57
|
|
@@ -61,9 +65,9 @@ module ActivePoro
|
|
61
65
|
|
62
66
|
# define setter method
|
63
67
|
define_method "#{target_name}=" do |member|
|
64
|
-
|
65
|
-
if member.respond_to?(
|
66
|
-
member.send "#{
|
68
|
+
singular_reflection_name = self.class.name.underscore
|
69
|
+
if member.respond_to?(singular_reflection_name) && member.send(singular_reflection_name) != self
|
70
|
+
member.send "#{singular_reflection_name}=", self
|
67
71
|
end
|
68
72
|
instance_variable_set("@#{target_name}", member)
|
69
73
|
end
|
@@ -79,33 +83,30 @@ module ActivePoro
|
|
79
83
|
define_method "#{target_name}=" do |member|
|
80
84
|
previous_member = instance_variable_get("@#{target_name}")
|
81
85
|
instance_variable_set("@#{target_name}", member)
|
82
|
-
|
86
|
+
|
87
|
+
singular_reflection_name = self.class.name.underscore
|
88
|
+
plural_reflection_name = singular_reflection_name.pluralize
|
89
|
+
|
83
90
|
# add myself to reflected association
|
84
|
-
if member.respond_to?(
|
85
|
-
member.send("#{
|
86
|
-
elsif member.respond_to?
|
87
|
-
reflected_members = member.send(
|
88
|
-
unless reflected_members.include? self
|
89
|
-
member.send("#{reflected_association_name.pluralize}=", reflected_members + [self])
|
90
|
-
end
|
91
|
+
if member.respond_to?(singular_reflection_name) && member.send(singular_reflection_name) != self
|
92
|
+
member.send("#{singular_reflection_name}=", self)
|
93
|
+
elsif member.respond_to? plural_reflection_name
|
94
|
+
reflected_members = member.send(plural_reflection_name)
|
95
|
+
member.send("#{plural_reflection_name}=", reflected_members + [self]) unless reflected_members.include? self
|
91
96
|
else
|
92
|
-
raise "Association definition missing: no #{
|
97
|
+
raise "Association definition missing: no #{singular_reflection_name} or #{plural_reflection_name} association defined in #{member.class}"
|
93
98
|
end
|
94
99
|
|
95
100
|
# remove myself from old reflected association
|
96
|
-
if previous_member.respond_to?
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
previous_reflected_members = previous_member.send(reflected_association_name.pluralize)
|
102
|
-
if previous_reflected_members.include? self
|
103
|
-
previous_member.send("#{reflected_association_name.pluralize}=", previous_reflected_members - [self])
|
104
|
-
end
|
101
|
+
if previous_member.respond_to? singular_reflection_name
|
102
|
+
previous_member.send("#{singular_reflection_name}=", nil) if previous_member.send(singular_reflection_name) == self
|
103
|
+
elsif previous_member.respond_to? plural_reflection_name
|
104
|
+
previous_reflected_members = previous_member.send(plural_reflection_name)
|
105
|
+
previous_member.send("#{plural_reflection_name}=", previous_reflected_members - [self]) if previous_reflected_members.include? self
|
105
106
|
elsif previous_member.nil?
|
106
|
-
# there
|
107
|
+
# there wasn't any previous member
|
107
108
|
else # there was a previous member
|
108
|
-
raise "Ghost association definition: no #{
|
109
|
+
raise "Ghost association definition: no #{singular_reflection_name} or #{plural_reflection_name} association defined in #{member.class}, although it was there previously, dirty contamination"
|
109
110
|
end
|
110
111
|
end
|
111
112
|
end
|
data/lib/active_poro/version.rb
CHANGED
data/spec/active_poro_spec.rb
CHANGED
@@ -131,26 +131,47 @@ describe 'ActivePoro' do
|
|
131
131
|
|
132
132
|
end
|
133
133
|
|
134
|
-
context 'when
|
134
|
+
context 'when fleas jump between dogs' do
|
135
135
|
|
136
136
|
let(:small_dog){ Dog.new('Small dog') }
|
137
137
|
|
138
138
|
it 'cannot be in two dogs at the same time' do
|
139
139
|
flea_a.dog = big_dog
|
140
|
+
flea_b.dog = big_dog
|
140
141
|
expect(flea_a.dog).to eq(big_dog)
|
141
|
-
expect(
|
142
|
+
expect(flea_b.dog).to eq(big_dog)
|
143
|
+
expect(big_dog.fleas).to eq([flea_a, flea_b])
|
142
144
|
|
143
|
-
# flea jumps from big dog to small dog
|
145
|
+
# flea A jumps from big dog to small dog
|
144
146
|
flea_a.dog = small_dog
|
145
147
|
expect(flea_a.dog).to eq(small_dog)
|
146
148
|
expect(small_dog.fleas).to eq([flea_a])
|
147
149
|
|
148
150
|
# flea A no longer in big dog
|
149
151
|
expect(big_dog.fleas).to_not include(flea_a)
|
150
|
-
expect(big_dog.fleas).to
|
152
|
+
expect(big_dog.fleas).to eq([flea_b])# sanity check
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
context 'when a dog catches some fleas from another dog' do
|
158
|
+
|
159
|
+
let(:small_dog){ Dog.new('Small dog') }
|
160
|
+
|
161
|
+
it 'the other dog losses part of its fleas' do
|
162
|
+
|
163
|
+
big_dog.fleas = [flea_a, flea_b]
|
164
|
+
|
165
|
+
# small_dog is close enough to bid_dog and it caches a flea
|
166
|
+
small_dog.fleas = [flea_a]
|
167
|
+
|
168
|
+
# flea A no longer in big dog
|
169
|
+
expect(big_dog.fleas).to_not include(flea_a)
|
170
|
+
expect(big_dog.fleas).to eq([flea_b])# sanity check
|
151
171
|
end
|
152
172
|
|
153
173
|
end
|
174
|
+
|
154
175
|
end
|
155
176
|
|
156
177
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
# Add coverage with simple_cov and codeclimate
|
2
|
+
# These must be the first lines in the file
|
3
|
+
require 'codeclimate-test-reporter'
|
4
|
+
require 'simplecov'
|
5
|
+
|
6
|
+
formatters = [SimpleCov::Formatter::HTMLFormatter]
|
7
|
+
formatters << CodeClimate::TestReporter::Formatter if ENV['CODECLIMATE_REPO_TOKEN']
|
8
|
+
|
9
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[*formatters]
|
10
|
+
SimpleCov.start do
|
11
|
+
add_filter '/spec/'
|
12
|
+
end
|
13
|
+
|
14
|
+
#######################################################################
|
15
|
+
|
1
16
|
require 'rubygems'
|
2
17
|
require 'pry'
|
3
18
|
|
@@ -1,17 +1,12 @@
|
|
1
1
|
# this is just a class that includes convenience methods for testing
|
2
2
|
# such as a giving it a name so that is easy to inspect
|
3
|
-
|
4
|
-
attr_accessor :name
|
5
|
-
|
6
|
-
def initialize(name)
|
7
|
-
self.name = name
|
8
|
-
end
|
3
|
+
BaseTestClass = Struct.new(:name) do
|
9
4
|
|
10
5
|
def to_s
|
11
6
|
name
|
12
7
|
end
|
13
8
|
|
14
9
|
def inspect
|
15
|
-
"\"#{
|
10
|
+
"\"#{self}\""
|
16
11
|
end
|
17
12
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_poro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miguel Diaz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-11-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,6 +66,34 @@ dependencies:
|
|
66
66
|
- - '>='
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.9.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.9.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: codeclimate-test-reporter
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.4.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.4.0
|
69
97
|
- !ruby/object:Gem::Dependency
|
70
98
|
name: activesupport
|
71
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -123,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
151
|
version: '0'
|
124
152
|
requirements: []
|
125
153
|
rubyforge_project:
|
126
|
-
rubygems_version: 2.0.
|
154
|
+
rubygems_version: 2.0.14
|
127
155
|
signing_key:
|
128
156
|
specification_version: 4
|
129
157
|
summary: Makes possible the use of has_many, has_one, belongs_to relations in POROs
|