acts_as_inheritable 0.0.1 → 0.0.2
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/.gitignore +1 -0
- data/README.md +40 -5
- data/acts_as_inheritable.gemspec +2 -2
- data/lib/acts_as_inheritable/version.rb +1 -1
- data/lib/acts_as_inheritable.rb +7 -0
- data/spec/acts_as_inheritable_spec.rb +34 -4
- data/spec/support/factories.rb +9 -0
- data/spec/support/migrations.rb +7 -0
- data/spec/support/models.rb +8 -5
- metadata +15 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 61f0d977c0caf99cd17883ba4e0f0e1a945be197
|
4
|
+
data.tar.gz: 28d9e8a7c3bb486dcfba2970eedbb25d4d4ec22e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 72b8c954ef211b5f35164393614ab2c062d418df267bfb5a5eeb771d5f4550e1d03f00898ddaacce18e1039fa04ce95e9902200faf3c39b7338f8bfae44b4773
|
7
|
+
data.tar.gz: e62c7d4bf845b2b476120537a674b6b05c9a8fa179f1d6de929a1c20beaaf082b812d18f6280cb53777b9d5a818a39fa8a5af0149fd886cda674b00505930f24
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# ActsAsInheritable
|
2
2
|
|
3
|
-
[](https://travis-ci.org/esbanarango/acts_as_inheritable) [](https://codeclimate.com/github/esbanarango/acts_as_inheritable/coverage) [](https://codeclimate.com/github/esbanarango/acts_as_inheritable)
|
3
|
+
[](https://badge.fury.io/rb/acts_as_inheritable) [](https://travis-ci.org/esbanarango/acts_as_inheritable) [](https://codeclimate.com/github/esbanarango/acts_as_inheritable/coverage) [](https://codeclimate.com/github/esbanarango/acts_as_inheritable)
|
4
4
|
|
5
|
-
|
5
|
+
_Acts As Inheritable_ is a Ruby Gem specifically written for Rails/ActiveRecord models. It is mean to be used with the [_Self-Referential Association_](#self-referential-association), or with a model having a `parent` that share the inheritable attributes. This will let you inherit any __attribute__ or __relation__ from the _parent_ model.
|
6
6
|
|
7
7
|
### Self-Referential Association
|
8
8
|
|
@@ -49,6 +49,7 @@ class Person < ActiveRecord::Base
|
|
49
49
|
has_many :children, class_name: 'Person', foreign_key: :parent_id
|
50
50
|
has_many :toys
|
51
51
|
has_many :shoes
|
52
|
+
has_one :pet
|
52
53
|
has_many :pictures, as: :imageable
|
53
54
|
|
54
55
|
# Callbacks
|
@@ -56,15 +57,49 @@ class Person < ActiveRecord::Base
|
|
56
57
|
before_validation :inherit_relations, on: :create
|
57
58
|
end
|
58
59
|
|
60
|
+
parent = Person.create(last_name: 'Arango', soccer_team: 'Verdolaga', favorite_color:'Green')
|
61
|
+
|
62
|
+
son = Person.create(parent: parent)
|
63
|
+
son.last_name # => Arango
|
64
|
+
son.soccer_team # => Verdolaga
|
65
|
+
son.favorite_color # => Green
|
66
|
+
|
59
67
|
````
|
68
|
+
### Available methods
|
69
|
+
By adding `acts_as_inheritable` to your models you will have access to these methods:
|
60
70
|
|
61
71
|
#### inherit_attributes
|
72
|
+
By default this method will only set values that are [blank?](http://api.rubyonrails.org/classes/Object.html#method-i-blank-3F).
|
73
|
+
|
62
74
|
##### params
|
63
|
-
- `force
|
64
|
-
- `not_force_for
|
75
|
+
- `force`: Default to true. Set the attribute even if it's _present_.
|
76
|
+
- `not_force_for`: Default to empty array. When setting `force` to _true_, you can also specify the attributes you don't want to overwrite.
|
77
|
+
|
78
|
+
#### inherit_relations
|
79
|
+
|
80
|
+
```ruby
|
65
81
|
|
66
|
-
|
82
|
+
class Person < ActiveRecord::Base
|
83
|
+
acts_as_inheritable
|
84
|
+
|
85
|
+
# Constants
|
86
|
+
INHERITABLE_ASSOCIATIONS = %w(pet)
|
67
87
|
|
88
|
+
# Associations
|
89
|
+
has_one :pet
|
90
|
+
|
91
|
+
# Callbacks
|
92
|
+
before_validation :inherit_relations, on: :create
|
93
|
+
end
|
94
|
+
|
95
|
+
parent = Person.create(last_name: 'Arango')
|
96
|
+
parent_pet = Pet.create(person: parent, name: 'Mango', breed:'Golden Retriver')
|
97
|
+
parent_pet.inspect #=> #<Pet id: 1, person_id: 1, name: "Mango", breed: "Golden Retriver">
|
98
|
+
|
99
|
+
son = Person.create(parent: parent)
|
100
|
+
son.pet.inspect # => #<Pet id: 2, person_id: 2, name: "Mango", breed: "Golden Retriver">
|
101
|
+
|
102
|
+
````
|
68
103
|
|
69
104
|
## Contributing
|
70
105
|
|
data/acts_as_inheritable.gemspec
CHANGED
@@ -23,10 +23,10 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency "factory_girl", "~> 4.5", ">= 4.5.0"
|
24
24
|
spec.add_development_dependency "faker", "~> 1.5", ">= 1.5.0"
|
25
25
|
spec.add_development_dependency "rspec", "~> 3.3", ">= 3.3.0"
|
26
|
-
spec.add_development_dependency "rspec-nc", "~> 0.2.0"
|
26
|
+
spec.add_development_dependency "rspec-nc", "~> 0.2", ">= 0.2.0"
|
27
27
|
spec.add_development_dependency "sqlite3", "~> 1.3"
|
28
28
|
spec.add_development_dependency "nyan-cat-formatter", "~> 0.11"
|
29
|
-
spec.add_development_dependency "codeclimate-test-reporter", "~> 0.4.3"
|
29
|
+
spec.add_development_dependency "codeclimate-test-reporter", "~> 0.4", ">= 0.4.3"
|
30
30
|
|
31
31
|
spec.add_dependency "activesupport", "~> 4"
|
32
32
|
spec.add_dependency "activerecord", "~> 4", ">= 4.1.2"
|
data/lib/acts_as_inheritable.rb
CHANGED
@@ -43,6 +43,7 @@ module ActsAsInheritable
|
|
43
43
|
|
44
44
|
def verify_parent_name(new_relation, model_parent)
|
45
45
|
parent_name = model_parent.class.to_s.downcase
|
46
|
+
return parent_name if new_relation.respond_to?(parent_name)
|
46
47
|
many_and_one_associations = model_parent.class.reflect_on_all_associations.select { |a| a.macro != :belongs_to }
|
47
48
|
many_and_one_associations.each do |association|
|
48
49
|
if association.klass.to_s.downcase == new_relation.class.to_s.downcase && association.options.has_key?(:as)
|
@@ -51,6 +52,12 @@ module ActsAsInheritable
|
|
51
52
|
break
|
52
53
|
end
|
53
54
|
end
|
55
|
+
# Relations has a diffeent name
|
56
|
+
unless new_relation.respond_to?(parent_name)
|
57
|
+
new_relation.class.reflections.keys.each do |reflection|
|
58
|
+
parent_name = reflection if new_relation.class.reflections[reflection].class_name == model_parent.class.name
|
59
|
+
end
|
60
|
+
end
|
54
61
|
parent_name
|
55
62
|
end
|
56
63
|
|
@@ -9,13 +9,43 @@ RSpec.describe "ActiveRecord::Base model with #acts_as_inheritable" do
|
|
9
9
|
let(:person){ create(:person, :with_parent, favorite_color: nil, last_name: nil, soccer_team: nil) }
|
10
10
|
let!(:person_parent) { person.parent }
|
11
11
|
it 'inherits values from his parent' do
|
12
|
+
person.inherit_attributes
|
12
13
|
expect(person.favorite_color).to eq person_parent.favorite_color
|
13
14
|
expect(person.last_name).to eq person_parent.last_name
|
14
15
|
expect(person.soccer_team).to eq person_parent.soccer_team
|
15
16
|
end
|
17
|
+
context 'when `force` is set to true' do
|
18
|
+
let(:person){ create(:person, :with_parent, favorite_color: nil, last_name: 'r3d3 restrepo', soccer_team: 'verdolaga') }
|
19
|
+
let!(:person_parent) { person.parent }
|
20
|
+
it 'inherits values from his parent even if those attributes have a value' do
|
21
|
+
person.inherit_attributes true
|
22
|
+
expect(person.favorite_color).to eq person_parent.favorite_color
|
23
|
+
expect(person.last_name).to eq person_parent.last_name
|
24
|
+
expect(person.soccer_team).to eq person_parent.soccer_team
|
25
|
+
end
|
26
|
+
context 'and `not_force_for` has attributes' do
|
27
|
+
it 'inherits values from his parent even if those attributes have a value but exclude then ones on `not_force_for`' do
|
28
|
+
person.inherit_attributes true, ['soccer_team']
|
29
|
+
expect(person.favorite_color).to eq person_parent.favorite_color
|
30
|
+
expect(person.last_name).to eq person_parent.last_name
|
31
|
+
expect(person.soccer_team).to eq 'verdolaga'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
16
35
|
end
|
17
36
|
|
18
37
|
describe '#inherit_relations' do
|
38
|
+
describe '`has_one` associations' do
|
39
|
+
let(:person_parent) { create(:person, :with_pet) }
|
40
|
+
let!(:person){ create(:person, parent: person_parent) }
|
41
|
+
|
42
|
+
it 're-creates the pet from the parent' do
|
43
|
+
expect {
|
44
|
+
person.inherit_relations
|
45
|
+
}.to change(Pet, :count).by(1)
|
46
|
+
expect(person.pet.id).to_not eq person_parent.pet.id
|
47
|
+
end
|
48
|
+
end
|
19
49
|
describe '`belongs_to` associations' do
|
20
50
|
let(:person_parent) { create(:person, :with_clan) }
|
21
51
|
let!(:person){ create(:person, parent: person_parent) }
|
@@ -49,14 +79,14 @@ RSpec.describe "ActiveRecord::Base model with #acts_as_inheritable" do
|
|
49
79
|
end
|
50
80
|
end
|
51
81
|
|
52
|
-
context 'when association
|
53
|
-
let(:person_parent) { create(:person, :
|
82
|
+
context 'when association uses a different name' do
|
83
|
+
let(:person_parent) { create(:person, :with_toys, number_of_toys: 2) }
|
54
84
|
let!(:person){ create(:person, parent: person_parent) }
|
55
85
|
|
56
|
-
it 're-creates all the
|
86
|
+
it 're-creates all the toys from the parent' do
|
57
87
|
expect {
|
58
88
|
person.inherit_relations
|
59
|
-
}.to change(
|
89
|
+
}.to change(Toy, :count).by(person_parent.toys.count)
|
60
90
|
end
|
61
91
|
end
|
62
92
|
end
|
data/spec/support/factories.rb
CHANGED
@@ -15,6 +15,10 @@ FactoryGirl.define do
|
|
15
15
|
clan { create(:clan) }
|
16
16
|
end
|
17
17
|
|
18
|
+
trait :with_pet do
|
19
|
+
pet { create(:pet) }
|
20
|
+
end
|
21
|
+
|
18
22
|
trait :with_toys do
|
19
23
|
transient do
|
20
24
|
number_of_toys 4
|
@@ -47,6 +51,11 @@ FactoryGirl.define do
|
|
47
51
|
name { Faker::Lorem.word }
|
48
52
|
end
|
49
53
|
|
54
|
+
factory :pet do
|
55
|
+
name { Faker::Lorem.word }
|
56
|
+
breed { Faker::Lorem.word }
|
57
|
+
end
|
58
|
+
|
50
59
|
factory :picture do
|
51
60
|
url { Faker::Internet.url }
|
52
61
|
place { Faker::Address.city }
|
data/spec/support/migrations.rb
CHANGED
data/spec/support/models.rb
CHANGED
@@ -5,7 +5,7 @@ class Person < ActiveRecord::Base
|
|
5
5
|
|
6
6
|
# Constants
|
7
7
|
INHERITABLE_ATTRIBUTES = %w(favorite_color last_name soccer_team)
|
8
|
-
INHERITABLE_ASSOCIATIONS = %w(shoes pictures clan)
|
8
|
+
INHERITABLE_ASSOCIATIONS = %w(shoes pictures clan toys pet)
|
9
9
|
|
10
10
|
# Associations
|
11
11
|
belongs_to :parent, class_name: 'Person'
|
@@ -13,10 +13,9 @@ class Person < ActiveRecord::Base
|
|
13
13
|
has_many :children, class_name: 'Person', foreign_key: :parent_id
|
14
14
|
has_many :toys
|
15
15
|
has_many :shoes
|
16
|
+
has_one :pet
|
16
17
|
has_many :pictures, as: :imageable
|
17
18
|
|
18
|
-
# Callbacks
|
19
|
-
before_validation :inherit_attributes, on: :create
|
20
19
|
end
|
21
20
|
|
22
21
|
class Clan < ActiveRecord::Base
|
@@ -34,8 +33,12 @@ class Shoe < ActiveRecord::Base
|
|
34
33
|
belongs_to :person
|
35
34
|
end
|
36
35
|
|
37
|
-
class
|
36
|
+
class Pet < ActiveRecord::Base
|
38
37
|
# Associations
|
39
|
-
belongs_to
|
38
|
+
belongs_to :person
|
40
39
|
end
|
41
40
|
|
41
|
+
class Picture < ActiveRecord::Base
|
42
|
+
# Associations
|
43
|
+
belongs_to :imageable, polymorphic: true
|
44
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_inheritable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Esteban Arango Medina
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10-
|
11
|
+
date: 2015-10-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -103,6 +103,9 @@ dependencies:
|
|
103
103
|
requirement: !ruby/object:Gem::Requirement
|
104
104
|
requirements:
|
105
105
|
- - "~>"
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0.2'
|
108
|
+
- - ">="
|
106
109
|
- !ruby/object:Gem::Version
|
107
110
|
version: 0.2.0
|
108
111
|
type: :development
|
@@ -110,6 +113,9 @@ dependencies:
|
|
110
113
|
version_requirements: !ruby/object:Gem::Requirement
|
111
114
|
requirements:
|
112
115
|
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0.2'
|
118
|
+
- - ">="
|
113
119
|
- !ruby/object:Gem::Version
|
114
120
|
version: 0.2.0
|
115
121
|
- !ruby/object:Gem::Dependency
|
@@ -145,6 +151,9 @@ dependencies:
|
|
145
151
|
requirement: !ruby/object:Gem::Requirement
|
146
152
|
requirements:
|
147
153
|
- - "~>"
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '0.4'
|
156
|
+
- - ">="
|
148
157
|
- !ruby/object:Gem::Version
|
149
158
|
version: 0.4.3
|
150
159
|
type: :development
|
@@ -152,6 +161,9 @@ dependencies:
|
|
152
161
|
version_requirements: !ruby/object:Gem::Requirement
|
153
162
|
requirements:
|
154
163
|
- - "~>"
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0.4'
|
166
|
+
- - ">="
|
155
167
|
- !ruby/object:Gem::Version
|
156
168
|
version: 0.4.3
|
157
169
|
- !ruby/object:Gem::Dependency
|
@@ -234,7 +246,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
234
246
|
version: '0'
|
235
247
|
requirements: []
|
236
248
|
rubyforge_project:
|
237
|
-
rubygems_version: 2.
|
249
|
+
rubygems_version: 2.2.2
|
238
250
|
signing_key:
|
239
251
|
specification_version: 4
|
240
252
|
summary: Inheritable behavior for models with parent.
|
@@ -245,4 +257,3 @@ test_files:
|
|
245
257
|
- spec/support/factories.rb
|
246
258
|
- spec/support/migrations.rb
|
247
259
|
- spec/support/models.rb
|
248
|
-
has_rdoc:
|