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 CHANGED
@@ -1,2 +1,2 @@
1
- source :rubygems
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('activemodel', '~> 3.0')
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. Last argument can be an options hash.
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
@@ -1,3 +1,3 @@
1
1
  module Entasis
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0.rc1"
3
3
  end
data/lib/entasis.rb CHANGED
@@ -5,6 +5,7 @@ module Entasis
5
5
  extend ActiveSupport::Autoload
6
6
 
7
7
  autoload :Model
8
+ autoload :Relations
8
9
  autoload :TransposeKeys
9
10
  autoload :Base
10
11
  end
@@ -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.4.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-01-29 00:00:00.000000000 Z
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: '0'
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