id 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,2 +1,2 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
  gemspec
data/Gemfile.lock CHANGED
@@ -5,7 +5,7 @@ PATH
5
5
  active_support
6
6
 
7
7
  GEM
8
- remote: http://rubygems.org/
8
+ remote: https://rubygems.org/
9
9
  specs:
10
10
  active_support (3.0.0)
11
11
  activesupport (= 3.0.0)
data/README.md ADDED
@@ -0,0 +1,6 @@
1
+ # id
2
+ ### simple models based on hashes
3
+
4
+ JSON is a great way to transfer data between systems, and it's easy to parse into a Ruby hash. But sometimes it's nice to have actual methods to call when you want to get attributes from your data, rather than coupling your entire codebase to the hash representation by littering it with calls to `fetch` or `[]`. The same goes for BSON documents stored in Mongo.
5
+
6
+ That's where `id` (as in Freud) comes in. You define your model classes using syntax that should look pretty familiar if you've used any popular Ruby ORMs - but `id` is not an ORM. Model objects defined with `id` have a constructor that accepts a hash, and you define the values of this hash that are made readable as fields - but that hash can come from any source.
data/id.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'id'
3
- s.version = '0.0.1'
3
+ s.version = '0.0.2'
4
4
  s.date = '2013-03-28'
5
5
  s.summary = "Simple models based on hashes"
6
6
  s.description = "Developed at On The Beach Ltd. Contact russell.dunphy@onthebeach.co.uk"
data/lib/id/model/all.rb CHANGED
@@ -2,3 +2,4 @@ require_relative 'field'
2
2
  require_relative 'association'
3
3
  require_relative 'has_one'
4
4
  require_relative 'has_many'
5
+ require_relative 'builder'
@@ -0,0 +1,45 @@
1
+ module Id
2
+ module Model
3
+ module Builder
4
+
5
+ def initialize(model, data={})
6
+ @model = model
7
+ @data = data
8
+ end
9
+
10
+ def build
11
+ model.new data
12
+ end
13
+
14
+ private
15
+
16
+ def set(f, value)
17
+ self.class.new(model, data.merge(f.to_s => ensure_hash(value)))
18
+ end
19
+
20
+ def ensure_hash(value)
21
+ case value
22
+ when Id::Model then value.data
23
+ when Array then value.map { |v| ensure_hash(v) }
24
+ else value end
25
+ end
26
+
27
+ attr_reader :model, :data
28
+
29
+ def self.included(base)
30
+ base.extend(FieldBuilder)
31
+ end
32
+
33
+ module FieldBuilder
34
+
35
+ def field(f)
36
+ define_method f do |value|
37
+ set(f, value)
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+ end
45
+ end
data/lib/id/model.rb CHANGED
@@ -1,18 +1,17 @@
1
1
  module Id
2
2
  module Model
3
-
4
3
  attr_reader :data
5
4
 
6
5
  def initialize(data)
7
6
  @data = Hash[data.map { |k, v| [k.to_s, v] }]
8
7
  end
9
8
 
9
+ private
10
+
10
11
  def self.included(base)
11
12
  base.extend(Descriptor)
12
13
  end
13
14
 
14
- private
15
-
16
15
  def memoize(f, &b)
17
16
  instance_variable_get("@#{f}") || instance_variable_set("@#{f}", b.call)
18
17
  end
@@ -20,14 +19,27 @@ module Id
20
19
  module Descriptor
21
20
  def field(f, options={})
22
21
  Field.new(self, f, options).define
22
+ builder_class.field f
23
23
  end
24
24
 
25
25
  def has_one(f, options={})
26
26
  HasOne.new(self, f, options).define
27
+ builder_class.field f
27
28
  end
28
29
 
29
30
  def has_many(f, options={})
30
31
  HasMany.new(self, f, options).define
32
+ builder_class.field f
33
+ end
34
+
35
+ def builder
36
+ builder_class.new(self)
37
+ end
38
+
39
+ private
40
+
41
+ def builder_class
42
+ @builder_class ||= Class.new { include Builder }
31
43
  end
32
44
  end
33
45
 
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe Id::Model::Association do
4
+
5
+ module Foo
6
+ module Bar
7
+ module Baz
8
+ class Quux
9
+ end
10
+ end
11
+ end
12
+ end
13
+
14
+ let (:model) { stub(name: "Foo::Bar::Baz::Quux") }
15
+ let (:has_one) { Id::Model::Association.new(model, "yak", {}) }
16
+
17
+ describe "hierarchy" do
18
+ it "builds the class and module hierarchy for the model" do
19
+ has_one.hierarchy.constants.should eq [
20
+ Foo::Bar::Baz::Quux,
21
+ Foo::Bar::Baz,
22
+ Foo::Bar,
23
+ Foo
24
+ ]
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ class BuilderModel
4
+ include Id::Model
5
+
6
+ field :foo
7
+ field :bar
8
+ has_one :nested_builder_model
9
+ has_many :nested_builder_models
10
+
11
+ class NestedBuilderModel
12
+ include Id::Model
13
+
14
+ field :baz
15
+ end
16
+
17
+ end
18
+
19
+ module Id
20
+ describe Model::Builder do
21
+
22
+ it 'models can be built using a builder' do
23
+ BuilderModel.builder.build.should be_a BuilderModel
24
+ end
25
+
26
+ it 'defines chainable setter methods for each field' do
27
+ model = BuilderModel.builder.foo(4).bar("hello cat").build
28
+ model.foo.should eq 4
29
+ model.bar.should eq "hello cat"
30
+ end
31
+
32
+ it 'allows setting of has_one associations using their respective builders' do
33
+ nested_model = BuilderModel::NestedBuilderModel.builder.baz(:quux).build
34
+ model = BuilderModel.builder.nested_builder_model(nested_model).build
35
+ model.nested_builder_model.baz.should eq :quux
36
+ end
37
+
38
+ it 'allows setting of has_many associations using their respective builders' do
39
+ nested_model = BuilderModel::NestedBuilderModel.builder.baz(:quux).build
40
+ model = BuilderModel.builder.nested_builder_models([nested_model]).build
41
+ model.nested_builder_models.first.baz.should eq :quux
42
+ end
43
+
44
+ end
45
+ end
File without changes
data/spec/lib/id_spec.rb CHANGED
@@ -74,28 +74,3 @@ describe Id::Model do
74
74
  end
75
75
  end
76
76
 
77
- describe Id::Model::HasOne do
78
-
79
- module Foo
80
- module Bar
81
- module Baz
82
- class Quux
83
- end
84
- end
85
- end
86
- end
87
-
88
- let (:model) { stub(name: "Foo::Bar::Baz::Quux") }
89
- let (:has_one) { Id::Model::HasOne.new(model, "yak", {}) }
90
-
91
- describe "hierarchy" do
92
- it "builds the class and module hierarchy for the model" do
93
- has_one.hierarchy.constants.should eq [
94
- Foo::Bar::Baz::Quux,
95
- Foo::Bar::Baz,
96
- Foo::Bar,
97
- Foo
98
- ]
99
- end
100
- end
101
- end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: id
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -72,6 +72,7 @@ files:
72
72
  - Gemfile
73
73
  - Gemfile.lock
74
74
  - LICENSE.md
75
+ - README.md
75
76
  - id.gemspec
76
77
  - lib/id.rb
77
78
  - lib/id/all.rb
@@ -79,9 +80,13 @@ files:
79
80
  - lib/id/model.rb
80
81
  - lib/id/model/all.rb
81
82
  - lib/id/model/association.rb
83
+ - lib/id/model/builder.rb
82
84
  - lib/id/model/field.rb
83
85
  - lib/id/model/has_many.rb
84
86
  - lib/id/model/has_one.rb
87
+ - spec/lib/id/model/association_spec.rb
88
+ - spec/lib/id/model/builder_spec.rb
89
+ - spec/lib/id/model_spec.rb
85
90
  - spec/lib/id_spec.rb
86
91
  - spec/spec_helper.rb
87
92
  homepage: http://rubygems.org/gems/id
@@ -109,5 +114,9 @@ signing_key:
109
114
  specification_version: 3
110
115
  summary: Simple models based on hashes
111
116
  test_files:
117
+ - spec/lib/id/model/association_spec.rb
118
+ - spec/lib/id/model/builder_spec.rb
119
+ - spec/lib/id/model_spec.rb
112
120
  - spec/lib/id_spec.rb
113
121
  - spec/spec_helper.rb
122
+ has_rdoc: