acts_as_inheritable 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Build Status](https://travis-ci.org/esbanarango/acts_as_inheritable.svg)](https://travis-ci.org/esbanarango/acts_as_inheritable) [![Test Coverage](https://codeclimate.com/github/esbanarango/acts_as_inheritable/badges/coverage.svg)](https://codeclimate.com/github/esbanarango/acts_as_inheritable/coverage) [![Code Climate](https://codeclimate.com/github/esbanarango/acts_as_inheritable/badges/gpa.svg)](https://codeclimate.com/github/esbanarango/acts_as_inheritable)
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/acts_as_inheritable.svg)](https://badge.fury.io/rb/acts_as_inheritable) [![Build Status](https://travis-ci.org/esbanarango/acts_as_inheritable.svg)](https://travis-ci.org/esbanarango/acts_as_inheritable) [![Test Coverage](https://codeclimate.com/github/esbanarango/acts_as_inheritable/badges/coverage.svg)](https://codeclimate.com/github/esbanarango/acts_as_inheritable/coverage) [![Code Climate](https://codeclimate.com/github/esbanarango/acts_as_inheritable/badges/gpa.svg)](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:
|