entasis 0.4.0 → 0.5.0.rc1
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.
- data/Gemfile +1 -1
- data/README.md +15 -4
- data/entasis.gemspec +1 -1
- data/lib/entasis/model.rb +5 -2
- data/lib/entasis/relations.rb +72 -0
- data/lib/entasis/version.rb +1 -1
- data/lib/entasis.rb +1 -0
- data/spec/relations_spec.rb +35 -0
- metadata +8 -5
data/Gemfile
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
gemspec
|
data/README.md
CHANGED
@@ -30,10 +30,21 @@ anon.errors # => {:name=>["can't be blank"]}>
|
|
30
30
|
Default behavior is to raise if any key in the hash given to `.new` or `#attributes=` is not defined,
|
31
31
|
this can be circumvented by passing `ignore_undefined: true` as options when defining your attributes.
|
32
32
|
|
33
|
+
|
34
|
+
Transposing keys
|
35
|
+
----------------
|
36
|
+
|
37
|
+
If you include the module `Entasis::TransposeKeys` after you have included `Entasis::Model`,
|
38
|
+
keys in the given hash will be downcased and underscored before calling the setter methods.
|
39
|
+
|
40
|
+
This can be very useful when you got hash with camelcased keys, for example from an external service serving XML soup.
|
41
|
+
|
42
|
+
|
33
43
|
Contributors
|
34
44
|
------------
|
35
45
|
|
36
|
-
Ingemar Edsborn (ingemar)
|
37
|
-
Joshua Davey (jgdavey)
|
38
|
-
Johnny Winn (nurugger07)
|
39
|
-
Jack Christensen (jackc)
|
46
|
+
- Ingemar Edsborn (ingemar)
|
47
|
+
- Joshua Davey (jgdavey)
|
48
|
+
- Johnny Winn (nurugger07)
|
49
|
+
- Jack Christensen (jackc)
|
50
|
+
|
data/entasis.gemspec
CHANGED
@@ -16,6 +16,6 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.files = Dir.glob("lib/**/*") + %w(Gemfile entasis.gemspec HISTORY README.md LICENSE)
|
17
17
|
s.test_files = Dir.glob('spec/*')
|
18
18
|
|
19
|
-
s.add_runtime_dependency
|
19
|
+
s.add_runtime_dependency 'activemodel', '~> 3.0'
|
20
20
|
s.add_development_dependency 'rspec', '~> 2.0'
|
21
21
|
end
|
data/lib/entasis/model.rb
CHANGED
@@ -3,8 +3,9 @@ module Entasis
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
+
include Entasis::Relations
|
6
7
|
include ActiveModel::Validations
|
7
|
-
class_attribute :attribute_names, :attributes_config, instance_writer: false
|
8
|
+
class_attribute :attribute_names, :attributes_config, :belongings, instance_writer: false
|
8
9
|
|
9
10
|
self.attribute_names ||= []
|
10
11
|
self.class_eval 'class UnknownAttributeError < StandardError; end'
|
@@ -13,7 +14,9 @@ module Entasis
|
|
13
14
|
module ClassMethods
|
14
15
|
##
|
15
16
|
#
|
16
|
-
# Takes a list of attribute names.
|
17
|
+
# Takes a list of attribute names.
|
18
|
+
#
|
19
|
+
# Last argument can be an options hash:
|
17
20
|
#
|
18
21
|
# ignore_undefined: true - Silently ignore any undefined attributes
|
19
22
|
#
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Entasis
|
2
|
+
module Relations
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
##
|
7
|
+
#
|
8
|
+
# Takes a list of relations. Speciefy each relation as a
|
9
|
+
# pluralization of corresponding class.
|
10
|
+
#
|
11
|
+
# Last argument can be an options hash:
|
12
|
+
#
|
13
|
+
# class: provide a custom class name
|
14
|
+
#
|
15
|
+
# This macro will give each instance corresponding
|
16
|
+
# setter and getter methods. Passing a collection of
|
17
|
+
# corresponding instances of the given class will populate
|
18
|
+
# the collection. Passing hashes will try to instanciate
|
19
|
+
# new objects of the relation's class.
|
20
|
+
#
|
21
|
+
# To set the inverse association and tie the objects together
|
22
|
+
# specify the +belongs_to+ relation in the other class.
|
23
|
+
#
|
24
|
+
def has_many(*relations)
|
25
|
+
options = relations.last.is_a?(Hash) ? relations.pop : {}
|
26
|
+
|
27
|
+
relations.each do |relation|
|
28
|
+
relation_model = (options[:class] || relation).to_s.singularize.camelize.constantize
|
29
|
+
|
30
|
+
self.class_eval <<-RUBY
|
31
|
+
def #{relation}=(resources)
|
32
|
+
@#{relation} = []
|
33
|
+
|
34
|
+
resources.each do |resource|
|
35
|
+
unless resource.is_a? #{relation_model}
|
36
|
+
resource = #{relation_model}.new resource
|
37
|
+
end
|
38
|
+
|
39
|
+
if resource.belongs_to? self.class
|
40
|
+
resource.send "\#{self.class.name.underscore}=", self
|
41
|
+
end
|
42
|
+
|
43
|
+
@#{relation} << resource
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def #{relation}
|
48
|
+
@#{relation} || []
|
49
|
+
end
|
50
|
+
RUBY
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# To complete the inverse relationship and tie two models togeter
|
56
|
+
# specify the +belongs_to+ relationship.
|
57
|
+
#
|
58
|
+
def belongs_to(*relations)
|
59
|
+
options = relations.last.is_a?(Hash) ? relations.pop : {}
|
60
|
+
|
61
|
+
self.belongings ||= []
|
62
|
+
self.belongings += relations.map(&:to_s).sort
|
63
|
+
|
64
|
+
attr_accessor *relations
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def belongs_to?(model)
|
69
|
+
self.belongings.include? model.to_s.underscore
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/entasis/version.rb
CHANGED
data/lib/entasis.rb
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Entasis::Relations do
|
4
|
+
let(:attributes) do
|
5
|
+
{
|
6
|
+
name: 'Volvo',
|
7
|
+
people: [{ name: 'Aslog' }],
|
8
|
+
passengers: [{ name: 'Gunnar' }]
|
9
|
+
}
|
10
|
+
end
|
11
|
+
let(:car) { Car.new }
|
12
|
+
let(:person) { car.people.first }
|
13
|
+
let(:passenger) { car.passengers.first }
|
14
|
+
|
15
|
+
describe '#attributes=' do
|
16
|
+
before { car.attributes = attributes }
|
17
|
+
|
18
|
+
context 'when given a hash' do
|
19
|
+
it 'creates a new instance of the relation' do
|
20
|
+
expect(car.name).to eq('Volvo')
|
21
|
+
expect(person).to be_a(Person)
|
22
|
+
expect(person.name).to eq('Aslog')
|
23
|
+
expect(person.car).to eq(car)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when relation definied with a custom class' do
|
28
|
+
it 'creates a new instance of the relation' do
|
29
|
+
expect(passenger).to be_a(Person)
|
30
|
+
expect(passenger.name).to eq('Gunnar')
|
31
|
+
expect(passenger.car).to eq(car)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: entasis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.5.0.rc1
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Ingemar Edsborn
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-02-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|
@@ -53,6 +53,7 @@ extra_rdoc_files: []
|
|
53
53
|
files:
|
54
54
|
- lib/entasis/base.rb
|
55
55
|
- lib/entasis/model.rb
|
56
|
+
- lib/entasis/relations.rb
|
56
57
|
- lib/entasis/transpose_keys.rb
|
57
58
|
- lib/entasis/version.rb
|
58
59
|
- lib/entasis.rb
|
@@ -62,6 +63,7 @@ files:
|
|
62
63
|
- README.md
|
63
64
|
- LICENSE
|
64
65
|
- spec/entasis_spec.rb
|
66
|
+
- spec/relations_spec.rb
|
65
67
|
- spec/spec_helper.rb
|
66
68
|
- spec/transpose_keys_spec.rb
|
67
69
|
homepage: http://github.com/ingemar/entasis
|
@@ -79,9 +81,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
79
81
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
82
|
none: false
|
81
83
|
requirements:
|
82
|
-
- - ! '
|
84
|
+
- - ! '>'
|
83
85
|
- !ruby/object:Gem::Version
|
84
|
-
version:
|
86
|
+
version: 1.3.1
|
85
87
|
requirements: []
|
86
88
|
rubyforge_project:
|
87
89
|
rubygems_version: 1.8.24
|
@@ -90,5 +92,6 @@ specification_version: 3
|
|
90
92
|
summary: A few neat methods for a basic class
|
91
93
|
test_files:
|
92
94
|
- spec/entasis_spec.rb
|
95
|
+
- spec/relations_spec.rb
|
93
96
|
- spec/spec_helper.rb
|
94
97
|
- spec/transpose_keys_spec.rb
|