acts_as_inheritable 0.0.1
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/.codeclimate.yml +39 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/.travis.yml +19 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +75 -0
- data/README.rdoc +3 -0
- data/Rakefile +10 -0
- data/acts_as_inheritable.gemspec +34 -0
- data/lib/acts_as_inheritable.rb +75 -0
- data/lib/acts_as_inheritable/version.rb +3 -0
- data/spec/acts_as_inheritable_spec.rb +64 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/support/database_helper.rb +26 -0
- data/spec/support/factories.rb +67 -0
- data/spec/support/migrations.rb +43 -0
- data/spec/support/models.rb +41 -0
- metadata +248 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: db1788d731e0bcdd74204824b7218dfe127d3fed
|
4
|
+
data.tar.gz: 8766188de301ee46e0b142b089a67b6addd1b8e8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a772d675fa5aa5c279cb05b218c92c136fbeac132bc25b455e5473cc46f7506eeb858d9d1086749717a8ad8a938a5e5abd582fc401dcbd5b5c6787419bf2b93a
|
7
|
+
data.tar.gz: 331e075044f1f3028bb67a892bb6f7ccb8f9c51bb87dc04994ba4a90e03986d6713a8b10816fb69595867485c11a53086378f2effbfacc29a996c82595f1b628
|
data/.codeclimate.yml
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# This is a sample .codeclimate.yml configured for Engine analysis on Code
|
2
|
+
# Climate Platform. For an overview of the Code Climate Platform, see here:
|
3
|
+
# http://docs.codeclimate.com/article/300-the-codeclimate-platform
|
4
|
+
|
5
|
+
# Under the engines key, you can configure which engines will analyze your repo.
|
6
|
+
# Each key is an engine name. For each value, you need to specify enabled: true
|
7
|
+
# to enable the engine as well as any other engines-specific configuration.
|
8
|
+
|
9
|
+
# For more details, see here:
|
10
|
+
# http://docs.codeclimate.com/article/289-configuring-your-repository-via-codeclimate-yml#platform
|
11
|
+
|
12
|
+
# For a list of all available engines, see here:
|
13
|
+
# http://docs.codeclimate.com/article/296-engines-available-engines
|
14
|
+
|
15
|
+
engines:
|
16
|
+
# to turn on an engine, add it here and set enabled to `true`
|
17
|
+
# to turn off an engine, set enabled to `false` or remove it
|
18
|
+
rubocop:
|
19
|
+
enabled: true
|
20
|
+
|
21
|
+
# Engines can analyze files and report issues on them, but you can separately
|
22
|
+
# decide which files will receive ratings based on those issues. This is
|
23
|
+
# specified by path patterns under the ratings key.
|
24
|
+
|
25
|
+
# For more details see here:
|
26
|
+
# http://docs.codeclimate.com/article/289-configuring-your-repository-via-codeclimate-yml#platform
|
27
|
+
|
28
|
+
# Note: If the ratings key is not specified, this will result in a 0.0 GPA on your dashboard.
|
29
|
+
|
30
|
+
ratings:
|
31
|
+
paths:
|
32
|
+
- lib/**
|
33
|
+
- "**.rb"
|
34
|
+
|
35
|
+
# You can globally exclude files from being analyzed by any engine using the
|
36
|
+
# exclude_paths key.
|
37
|
+
|
38
|
+
exclude_paths:
|
39
|
+
- spec/**
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Esteban Arango Medina
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# ActsAsInheritable
|
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)
|
4
|
+
|
5
|
+
This is gem 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
|
+
|
7
|
+
### Self-Referential Association
|
8
|
+
|
9
|
+
This is a code example on how to implement _Self-Referential Association_
|
10
|
+
|
11
|
+
````ruby
|
12
|
+
class Person < ActiveRecord::Base
|
13
|
+
belongs_to :parent, class: Person
|
14
|
+
has_many :children, class: Person, foreign_key: :parent_id
|
15
|
+
has_many :grandchildren, class: Person, through: :children, source: :children
|
16
|
+
end
|
17
|
+
````
|
18
|
+
|
19
|
+
## Installation
|
20
|
+
|
21
|
+
Add this line to your application's Gemfile:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
gem 'acts_as_inheritable'
|
25
|
+
```
|
26
|
+
|
27
|
+
And then execute:
|
28
|
+
|
29
|
+
$ bundle
|
30
|
+
|
31
|
+
Or install it yourself as:
|
32
|
+
|
33
|
+
$ gem install acts_as_inheritable
|
34
|
+
|
35
|
+
## Usage
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
|
39
|
+
class Person < ActiveRecord::Base
|
40
|
+
acts_as_inheritable
|
41
|
+
|
42
|
+
# Constants
|
43
|
+
INHERITABLE_ATTRIBUTES = %w(favorite_color last_name soccer_team)
|
44
|
+
INHERITABLE_ASSOCIATIONS = %w(shoes pictures clan)
|
45
|
+
|
46
|
+
# Associations
|
47
|
+
belongs_to :parent, class_name: 'Person'
|
48
|
+
belongs_to :clan
|
49
|
+
has_many :children, class_name: 'Person', foreign_key: :parent_id
|
50
|
+
has_many :toys
|
51
|
+
has_many :shoes
|
52
|
+
has_many :pictures, as: :imageable
|
53
|
+
|
54
|
+
# Callbacks
|
55
|
+
before_validation :inherit_attributes, on: :create
|
56
|
+
before_validation :inherit_relations, on: :create
|
57
|
+
end
|
58
|
+
|
59
|
+
````
|
60
|
+
|
61
|
+
#### inherit_attributes
|
62
|
+
##### params
|
63
|
+
- `force` | default to true. Set the attribute even if it's _present_.
|
64
|
+
- `not_force_for` | array of attributes. When setting `force` to _true_, you can also specify the attributes you don't want to overwrite.
|
65
|
+
|
66
|
+
__inherit_attributes__ method by default will only set values that are [blank?](http://api.rubyonrails.org/classes/Object.html#method-i-blank-3F).
|
67
|
+
|
68
|
+
|
69
|
+
## Contributing
|
70
|
+
|
71
|
+
1. Fork it ( https://github.com/[my-github-username]/acts_as_inheritable/fork )
|
72
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
73
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
74
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
75
|
+
5. Create a new Pull Request
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'rspec/core/rake_task'
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
|
4
|
+
# Default directory to look in is `/specs`
|
5
|
+
# Run with `rake spec`
|
6
|
+
RSpec::Core::RakeTask.new(:spec) do |task|
|
7
|
+
task.rspec_opts = ['--color', '--format', 'nested']
|
8
|
+
end
|
9
|
+
|
10
|
+
task default: :spec
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'acts_as_inheritable/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "acts_as_inheritable"
|
8
|
+
spec.version = ActsAsInheritable::VERSION
|
9
|
+
spec.authors = ["Esteban Arango Medina"]
|
10
|
+
spec.email = ["marranoparael31@gmail.com"]
|
11
|
+
spec.summary = %q{Inheritable behavior for models with parent.}
|
12
|
+
spec.description = %q{This gem will let you inherit any attribute or relation from the parent model.}
|
13
|
+
spec.homepage = "https://github.com/esbanarango/acts_as_inheritable"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "factory_girl", "~> 4.5", ">= 4.5.0"
|
24
|
+
spec.add_development_dependency "faker", "~> 1.5", ">= 1.5.0"
|
25
|
+
spec.add_development_dependency "rspec", "~> 3.3", ">= 3.3.0"
|
26
|
+
spec.add_development_dependency "rspec-nc", "~> 0.2.0"
|
27
|
+
spec.add_development_dependency "sqlite3", "~> 1.3"
|
28
|
+
spec.add_development_dependency "nyan-cat-formatter", "~> 0.11"
|
29
|
+
spec.add_development_dependency "codeclimate-test-reporter", "~> 0.4.3"
|
30
|
+
|
31
|
+
spec.add_dependency "activesupport", "~> 4"
|
32
|
+
spec.add_dependency "activerecord", "~> 4", ">= 4.1.2"
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require "acts_as_inheritable/version"
|
3
|
+
|
4
|
+
module ActsAsInheritable
|
5
|
+
def acts_as_inheritable
|
6
|
+
class_eval do
|
7
|
+
def has_parent?
|
8
|
+
parent.present?
|
9
|
+
end
|
10
|
+
|
11
|
+
# This is an inheritable recursive method that iterates over all of the
|
12
|
+
# relations defined on `INHERITABLE_ASSOCIATIONS`. For each instance on
|
13
|
+
# each relation it re-creates it.
|
14
|
+
def inherit_relations(model_parent = send(:parent), current = self)
|
15
|
+
if model_parent && model_parent.class.const_defined?("INHERITABLE_ASSOCIATIONS")
|
16
|
+
model_parent.class::INHERITABLE_ASSOCIATIONS.each do |relation|
|
17
|
+
parent_relation = model_parent.send(relation)
|
18
|
+
relation_instances = parent_relation.respond_to?(:each) ? parent_relation : [parent_relation].compact
|
19
|
+
relation_instances.each do |relation_instance|
|
20
|
+
inherit_instance(current, model_parent, relation, relation_instance)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def inherit_instance(current, model_parent, relation, relation_instance)
|
27
|
+
new_relation = relation_instance.dup
|
28
|
+
belongs_to_associations_names = model_parent.class.reflect_on_all_associations(:belongs_to).collect(&:name)
|
29
|
+
saved =
|
30
|
+
if belongs_to_associations_names.include?(relation.to_sym)
|
31
|
+
# Is a `belongs_to` association
|
32
|
+
new_relation = relation_instance.duplicate! if relation_instance.respond_to?(:duplicate!)
|
33
|
+
current.send("#{relation}=", new_relation)
|
34
|
+
current.save
|
35
|
+
else
|
36
|
+
# Is a `has_one | has_many` association
|
37
|
+
parent_name = verify_parent_name(new_relation, model_parent)
|
38
|
+
new_relation.send("#{parent_name}=", current)
|
39
|
+
new_relation.save
|
40
|
+
end
|
41
|
+
inherit_relations(relation_instance, new_relation) if saved
|
42
|
+
end
|
43
|
+
|
44
|
+
def verify_parent_name(new_relation, model_parent)
|
45
|
+
parent_name = model_parent.class.to_s.downcase
|
46
|
+
many_and_one_associations = model_parent.class.reflect_on_all_associations.select { |a| a.macro != :belongs_to }
|
47
|
+
many_and_one_associations.each do |association|
|
48
|
+
if association.klass.to_s.downcase == new_relation.class.to_s.downcase && association.options.has_key?(:as)
|
49
|
+
as = association.options[:as].to_s
|
50
|
+
parent_name = as if new_relation.respond_to?(as) && !new_relation.respond_to?(parent_name)
|
51
|
+
break
|
52
|
+
end
|
53
|
+
end
|
54
|
+
parent_name
|
55
|
+
end
|
56
|
+
|
57
|
+
def inherit_attributes(force = false, not_force_for=[])
|
58
|
+
if has_parent?
|
59
|
+
# Attributes
|
60
|
+
self.class::INHERITABLE_ATTRIBUTES.each do |attribute|
|
61
|
+
current_val = send(attribute)
|
62
|
+
if (force && !not_force_for.include?(attribute)) || current_val.blank?
|
63
|
+
send("#{attribute}=", parent.send(attribute))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
if defined?(ActiveRecord)
|
71
|
+
# Extend ActiveRecord's functionality
|
72
|
+
ActiveRecord::Base.send :extend, ActsAsInheritable
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'support/migrations'
|
3
|
+
require 'support/factories'
|
4
|
+
require 'support/models'
|
5
|
+
|
6
|
+
RSpec.describe "ActiveRecord::Base model with #acts_as_inheritable" do
|
7
|
+
|
8
|
+
describe '#inherit_attributes' do
|
9
|
+
let(:person){ create(:person, :with_parent, favorite_color: nil, last_name: nil, soccer_team: nil) }
|
10
|
+
let!(:person_parent) { person.parent }
|
11
|
+
it 'inherits values from his parent' do
|
12
|
+
expect(person.favorite_color).to eq person_parent.favorite_color
|
13
|
+
expect(person.last_name).to eq person_parent.last_name
|
14
|
+
expect(person.soccer_team).to eq person_parent.soccer_team
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#inherit_relations' do
|
19
|
+
describe '`belongs_to` associations' do
|
20
|
+
let(:person_parent) { create(:person, :with_clan) }
|
21
|
+
let!(:person){ create(:person, parent: person_parent) }
|
22
|
+
|
23
|
+
it 're-creates the clan from the parent' do
|
24
|
+
expect {
|
25
|
+
person.inherit_relations
|
26
|
+
}.to change(Clan, :count).by(1)
|
27
|
+
expect(person.clan.id).to_not eq person_parent.clan.id
|
28
|
+
end
|
29
|
+
end
|
30
|
+
describe '`has_many` associations' do
|
31
|
+
|
32
|
+
let(:person_parent) { create(:person, :with_shoes, number_of_shoes: 2) }
|
33
|
+
let!(:person){ create(:person, parent: person_parent) }
|
34
|
+
|
35
|
+
it 're-creates all the shoes from the parent' do
|
36
|
+
expect {
|
37
|
+
person.inherit_relations
|
38
|
+
}.to change(Shoe, :count).by(person_parent.shoes.count)
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when association is polymorphic' do
|
42
|
+
let(:person_parent) { create(:person, :with_pictures, number_of_pictures: 2) }
|
43
|
+
let!(:person){ create(:person, parent: person_parent) }
|
44
|
+
|
45
|
+
it 're-creates all the pictures from the parent' do
|
46
|
+
expect {
|
47
|
+
person.inherit_relations
|
48
|
+
}.to change(Picture, :count).by(person_parent.pictures.count)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'when association is polymorphic' do
|
53
|
+
let(:person_parent) { create(:person, :with_pictures, number_of_pictures: 2) }
|
54
|
+
let!(:person){ create(:person, parent: person_parent) }
|
55
|
+
|
56
|
+
it 're-creates all the pictures from the parent' do
|
57
|
+
expect {
|
58
|
+
person.inherit_relations
|
59
|
+
}.to change(Picture, :count).by(person_parent.pictures.count)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
def connect_to_databse
|
4
|
+
ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
|
5
|
+
end
|
6
|
+
|
7
|
+
def clear_database
|
8
|
+
ActiveRecord::Base.descendants.each do |model|
|
9
|
+
model.delete_all if model.table_exists?
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def reset_database
|
14
|
+
ActiveRecord::Base.descendants.map(&:reset_column_information)
|
15
|
+
ActiveRecord::Base.connection.disconnect!
|
16
|
+
connect_to_databse
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize_database(&block)
|
20
|
+
reset_database
|
21
|
+
ActiveRecord::Schema.define(&block)
|
22
|
+
end
|
23
|
+
|
24
|
+
I18n.enforce_available_locales = false
|
25
|
+
ActiveRecord::Migration.verbose = false
|
26
|
+
connect_to_databse
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'faker'
|
2
|
+
|
3
|
+
FactoryGirl.define do
|
4
|
+
factory :person do
|
5
|
+
first_name { Faker::Name.first_name }
|
6
|
+
favorite_color { Faker::Commerce.color }
|
7
|
+
last_name { Faker::Name.last_name }
|
8
|
+
soccer_team { Faker::App.name }
|
9
|
+
|
10
|
+
trait :with_parent do
|
11
|
+
parent { create(:person) }
|
12
|
+
end
|
13
|
+
|
14
|
+
trait :with_clan do
|
15
|
+
clan { create(:clan) }
|
16
|
+
end
|
17
|
+
|
18
|
+
trait :with_toys do
|
19
|
+
transient do
|
20
|
+
number_of_toys 4
|
21
|
+
end
|
22
|
+
after :create do |person, evaluator|
|
23
|
+
create_list :toy, evaluator.number_of_toys, owner: person
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
trait :with_shoes do
|
28
|
+
transient do
|
29
|
+
number_of_shoes 4
|
30
|
+
end
|
31
|
+
after :create do |person, evaluator|
|
32
|
+
create_list :shoe, evaluator.number_of_shoes, person: person
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
trait :with_pictures do
|
37
|
+
transient do
|
38
|
+
number_of_pictures 4
|
39
|
+
end
|
40
|
+
after :create do |person, evaluator|
|
41
|
+
create_list :picture, evaluator.number_of_pictures, imageable: person
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
factory :clan do
|
47
|
+
name { Faker::Lorem.word }
|
48
|
+
end
|
49
|
+
|
50
|
+
factory :picture do
|
51
|
+
url { Faker::Internet.url }
|
52
|
+
place { Faker::Address.city }
|
53
|
+
end
|
54
|
+
|
55
|
+
factory :toy do
|
56
|
+
friendly { [true, false].sample}
|
57
|
+
material { Faker::Lorem.word }
|
58
|
+
color { Faker::Commerce.color }
|
59
|
+
brand { Faker::Company.name }
|
60
|
+
end
|
61
|
+
|
62
|
+
factory :shoe do
|
63
|
+
sneakers { [true, false].sample}
|
64
|
+
size { Faker::Number.number(3) }
|
65
|
+
brand { Faker::Company.name }
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'support/database_helper'
|
2
|
+
|
3
|
+
initialize_database do
|
4
|
+
|
5
|
+
create_table :people do |t|
|
6
|
+
t.string :first_name
|
7
|
+
t.string :age
|
8
|
+
t.string :favorite_color
|
9
|
+
t.string :last_name
|
10
|
+
t.string :soccer_team
|
11
|
+
end
|
12
|
+
add_reference :people, :parent, index: true
|
13
|
+
|
14
|
+
create_table :toys do |t|
|
15
|
+
t.references :person, index: true
|
16
|
+
t.boolean :friendly
|
17
|
+
t.string :material
|
18
|
+
t.string :color
|
19
|
+
t.string :brand
|
20
|
+
end
|
21
|
+
add_foreign_key :toys, :people
|
22
|
+
|
23
|
+
create_table :shoes do |t|
|
24
|
+
t.references :person, index: true
|
25
|
+
t.boolean :sneakers
|
26
|
+
t.integer :size
|
27
|
+
t.string :brand
|
28
|
+
end
|
29
|
+
add_foreign_key :shoes, :people
|
30
|
+
|
31
|
+
create_table :pictures do |t|
|
32
|
+
t.references :imageable, polymorphic: true, index: true
|
33
|
+
t.string :url
|
34
|
+
t.string :place
|
35
|
+
end
|
36
|
+
|
37
|
+
create_table :clans do |t|
|
38
|
+
t.string :name
|
39
|
+
end
|
40
|
+
add_reference :people, :clan, index: true
|
41
|
+
add_foreign_key :people, :clans
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'acts_as_inheritable'
|
2
|
+
|
3
|
+
class Person < ActiveRecord::Base
|
4
|
+
acts_as_inheritable
|
5
|
+
|
6
|
+
# Constants
|
7
|
+
INHERITABLE_ATTRIBUTES = %w(favorite_color last_name soccer_team)
|
8
|
+
INHERITABLE_ASSOCIATIONS = %w(shoes pictures clan)
|
9
|
+
|
10
|
+
# Associations
|
11
|
+
belongs_to :parent, class_name: 'Person'
|
12
|
+
belongs_to :clan
|
13
|
+
has_many :children, class_name: 'Person', foreign_key: :parent_id
|
14
|
+
has_many :toys
|
15
|
+
has_many :shoes
|
16
|
+
has_many :pictures, as: :imageable
|
17
|
+
|
18
|
+
# Callbacks
|
19
|
+
before_validation :inherit_attributes, on: :create
|
20
|
+
end
|
21
|
+
|
22
|
+
class Clan < ActiveRecord::Base
|
23
|
+
# Associations
|
24
|
+
has_many :people
|
25
|
+
end
|
26
|
+
|
27
|
+
class Toy < ActiveRecord::Base
|
28
|
+
# Associations
|
29
|
+
belongs_to :owner, class_name: 'Person', foreign_key: :person_id
|
30
|
+
end
|
31
|
+
|
32
|
+
class Shoe < ActiveRecord::Base
|
33
|
+
# Associations
|
34
|
+
belongs_to :person
|
35
|
+
end
|
36
|
+
|
37
|
+
class Picture < ActiveRecord::Base
|
38
|
+
# Associations
|
39
|
+
belongs_to :imageable, polymorphic: true
|
40
|
+
end
|
41
|
+
|
metadata
ADDED
@@ -0,0 +1,248 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: acts_as_inheritable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Esteban Arango Medina
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-10-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: factory_girl
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '4.5'
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 4.5.0
|
51
|
+
type: :development
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - "~>"
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '4.5'
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 4.5.0
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: faker
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '1.5'
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 1.5.0
|
71
|
+
type: :development
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - "~>"
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '1.5'
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 1.5.0
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: rspec
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - "~>"
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '3.3'
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: 3.3.0
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '3.3'
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: 3.3.0
|
101
|
+
- !ruby/object:Gem::Dependency
|
102
|
+
name: rspec-nc
|
103
|
+
requirement: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - "~>"
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: 0.2.0
|
108
|
+
type: :development
|
109
|
+
prerelease: false
|
110
|
+
version_requirements: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - "~>"
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: 0.2.0
|
115
|
+
- !ruby/object:Gem::Dependency
|
116
|
+
name: sqlite3
|
117
|
+
requirement: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - "~>"
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '1.3'
|
122
|
+
type: :development
|
123
|
+
prerelease: false
|
124
|
+
version_requirements: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - "~>"
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '1.3'
|
129
|
+
- !ruby/object:Gem::Dependency
|
130
|
+
name: nyan-cat-formatter
|
131
|
+
requirement: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - "~>"
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0.11'
|
136
|
+
type: :development
|
137
|
+
prerelease: false
|
138
|
+
version_requirements: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - "~>"
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0.11'
|
143
|
+
- !ruby/object:Gem::Dependency
|
144
|
+
name: codeclimate-test-reporter
|
145
|
+
requirement: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - "~>"
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: 0.4.3
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
requirements:
|
154
|
+
- - "~>"
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: 0.4.3
|
157
|
+
- !ruby/object:Gem::Dependency
|
158
|
+
name: activesupport
|
159
|
+
requirement: !ruby/object:Gem::Requirement
|
160
|
+
requirements:
|
161
|
+
- - "~>"
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: '4'
|
164
|
+
type: :runtime
|
165
|
+
prerelease: false
|
166
|
+
version_requirements: !ruby/object:Gem::Requirement
|
167
|
+
requirements:
|
168
|
+
- - "~>"
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
version: '4'
|
171
|
+
- !ruby/object:Gem::Dependency
|
172
|
+
name: activerecord
|
173
|
+
requirement: !ruby/object:Gem::Requirement
|
174
|
+
requirements:
|
175
|
+
- - "~>"
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '4'
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: 4.1.2
|
181
|
+
type: :runtime
|
182
|
+
prerelease: false
|
183
|
+
version_requirements: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - "~>"
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '4'
|
188
|
+
- - ">="
|
189
|
+
- !ruby/object:Gem::Version
|
190
|
+
version: 4.1.2
|
191
|
+
description: This gem will let you inherit any attribute or relation from the parent
|
192
|
+
model.
|
193
|
+
email:
|
194
|
+
- marranoparael31@gmail.com
|
195
|
+
executables: []
|
196
|
+
extensions: []
|
197
|
+
extra_rdoc_files: []
|
198
|
+
files:
|
199
|
+
- ".codeclimate.yml"
|
200
|
+
- ".gitignore"
|
201
|
+
- ".rspec"
|
202
|
+
- ".travis.yml"
|
203
|
+
- Gemfile
|
204
|
+
- LICENSE.txt
|
205
|
+
- README.md
|
206
|
+
- README.rdoc
|
207
|
+
- Rakefile
|
208
|
+
- acts_as_inheritable.gemspec
|
209
|
+
- lib/acts_as_inheritable.rb
|
210
|
+
- lib/acts_as_inheritable/version.rb
|
211
|
+
- spec/acts_as_inheritable_spec.rb
|
212
|
+
- spec/spec_helper.rb
|
213
|
+
- spec/support/database_helper.rb
|
214
|
+
- spec/support/factories.rb
|
215
|
+
- spec/support/migrations.rb
|
216
|
+
- spec/support/models.rb
|
217
|
+
homepage: https://github.com/esbanarango/acts_as_inheritable
|
218
|
+
licenses:
|
219
|
+
- MIT
|
220
|
+
metadata: {}
|
221
|
+
post_install_message:
|
222
|
+
rdoc_options: []
|
223
|
+
require_paths:
|
224
|
+
- lib
|
225
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - ">="
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '0'
|
230
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
231
|
+
requirements:
|
232
|
+
- - ">="
|
233
|
+
- !ruby/object:Gem::Version
|
234
|
+
version: '0'
|
235
|
+
requirements: []
|
236
|
+
rubyforge_project:
|
237
|
+
rubygems_version: 2.4.3
|
238
|
+
signing_key:
|
239
|
+
specification_version: 4
|
240
|
+
summary: Inheritable behavior for models with parent.
|
241
|
+
test_files:
|
242
|
+
- spec/acts_as_inheritable_spec.rb
|
243
|
+
- spec/spec_helper.rb
|
244
|
+
- spec/support/database_helper.rb
|
245
|
+
- spec/support/factories.rb
|
246
|
+
- spec/support/migrations.rb
|
247
|
+
- spec/support/models.rb
|
248
|
+
has_rdoc:
|