collector 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 1.9.2
data/Gemfile CHANGED
@@ -1,6 +1,7 @@
1
1
  source "https://rubygems.org"
2
2
 
3
3
  group :test do
4
+ gem "rake", "~> 0.9.2.2"
4
5
  gem "turn", "~> 0.9.6"
5
6
  gem "minitest", "~> 4.1.0"
6
7
  gem "mocha", "~> 0.12.7", require: false
data/README.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # Collector
2
2
 
3
+ [![Build Status](https://travis-ci.org/brandonweiss/collector.png)](https://travis-ci.org/brandonweiss/collector)
3
4
  [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/brandonweiss/collector)
4
5
 
5
- _Collector isn't ready for use just yet. When it has a basic feature set and is stable I will bump the minor version (to 0.1.0). Until then it's still effectively pre-release._
6
+ _Collector isn't ready for use just yet. And I don't mean it's unstable or alpha, I mean literally it doesn't do anything yet. When the basic feature set is ready I will bump the minor version (to 0.1.0)._
6
7
 
7
8
  Collector is an implementation of the Repository Pattern for MongoDB. For those new to the Repository Pattern, it is a Facade that isolates the persistence layer from your application. If you're familiar with Rails, or more specifically ActiveRecord or most other ORMs, you'll know that the models and persistence layer are tightly coupled—literally they are the same object. That pattern is a great way to cut your teeth, but ultimately it's a terrible design. Your application does not and should not care about how its data is persisted. Collector will help with that.
8
9
 
@@ -22,12 +23,55 @@ Or install it yourself as:
22
23
 
23
24
  ## Usage
24
25
 
25
- ### Configure a connection
26
+ ### Configuration
27
+
28
+ Set up a connection.
26
29
 
27
30
  ```ruby
28
31
  Collector.connection = Mongo::Connection.new
29
32
  ```
30
33
 
34
+ ### Models
35
+
36
+ Include `Collector::Model` in your domain objects to turn them into models. Create accessors for any attributes.
37
+
38
+ ```ruby
39
+ class Pickle
40
+
41
+ include Collector::Model
42
+
43
+ attr_accessor :brine, :started_at
44
+
45
+ end
46
+ ```
47
+
48
+ Models can be instantiated with a hash of attributes.
49
+
50
+ ```ruby
51
+ Pickle.new(brine: "vinegar", started_at: Time.now)
52
+ ```
53
+
54
+ Models automatically create and update timestamps for `created_at` and `updated_at`.
55
+
56
+ ### Repositories
57
+
58
+ Include `Collector::Repository` in your repository objects to turn them into repositories. Use the same inflection as your model's name (singular).
59
+
60
+ ```ruby
61
+ class PickleRepository
62
+
63
+ include Collector::Repository
64
+
65
+ end
66
+ ```
67
+
68
+ Repositories can save models.
69
+
70
+ ```ruby
71
+ pickle = Pickle.new(brine: "vinegar", started_at: Time.now)
72
+ PickleRepository.save(pickle)
73
+ ```
74
+
31
75
  ## Contributing
32
76
 
33
77
  1. Fork it
@@ -23,5 +23,11 @@ module Collector
23
23
  @updated_at = Time.now.utc
24
24
  end
25
25
 
26
+ def attributes
27
+ instance_variables.each_with_object({}) do |instance_variable, hash|
28
+ hash[instance_variable.to_s[1..-1]] = instance_variable_get(instance_variable)
29
+ end
30
+ end
31
+
26
32
  end
27
33
  end
@@ -21,6 +21,20 @@ module Collector
21
21
  name.to_s.gsub("Repository", "").constantize
22
22
  end
23
23
 
24
+ def save(model)
25
+ model.touch
26
+ save_without_updating_timestamps(model)
27
+ end
28
+
29
+ def save_without_updating_timestamps(model)
30
+ attributes = serialize(model)
31
+ collection.insert(attributes)
32
+ end
33
+
34
+ def serialize(model)
35
+ model.attributes.reject { |key, val| val.nil? }
36
+ end
37
+
24
38
  end
25
39
 
26
40
  end
@@ -1,3 +1,3 @@
1
1
  module Collector
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
@@ -34,8 +34,7 @@ describe Collector::Model do
34
34
  test_model.updated_at.must_equal now
35
35
  end
36
36
 
37
- describe "touch" do
38
-
37
+ describe "#touch" do
39
38
  it "sets the timestamps" do
40
39
  Timecop.freeze
41
40
 
@@ -60,7 +59,14 @@ describe Collector::Model do
60
59
 
61
60
  test_model.created_at.must_equal now.utc
62
61
  end
62
+ end
63
63
 
64
+ describe "#attributes" do
65
+ it "returns a hash of instance variable names and their values" do
66
+ TestModel.send(:attr_writer, :name)
67
+ test_model = TestModel.new(name: "Foobar", created_at: 123)
68
+ test_model.attributes.must_equal({ "name" => "Foobar", "created_at" => 123 })
69
+ end
64
70
  end
65
71
 
66
72
  end
@@ -29,4 +29,31 @@ describe Collector::Repository do
29
29
  end
30
30
  end
31
31
 
32
+ describe "#save" do
33
+ it "touches the model and then saves it" do
34
+ model = mock(:touch)
35
+ TestRepository.expects(:save_without_updating_timestamps).with(model)
36
+ TestRepository.save(model)
37
+ end
38
+ end
39
+
40
+ describe "#save_without_updating_timestamps" do
41
+ it "serializes the model and then inserts it into the collection" do
42
+ model = stub()
43
+ TestRepository.expects(:serialize).with(model).returns({ foo: "bar" })
44
+
45
+ collection = mock(insert: { foo: "bar" })
46
+ TestRepository.stubs(:collection).returns(collection)
47
+
48
+ TestRepository.save_without_updating_timestamps(model)
49
+ end
50
+ end
51
+
52
+ describe "#serialize" do
53
+ it "returns a models attributes without nil values" do
54
+ model = mock(attributes: { foo: "bar", nothing: nil })
55
+ TestRepository.serialize(model).must_equal({ foo: "bar" })
56
+ end
57
+ end
58
+
32
59
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: collector
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-06 00:00:00.000000000 Z
12
+ date: 2012-11-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -35,6 +35,7 @@ extensions: []
35
35
  extra_rdoc_files: []
36
36
  files:
37
37
  - .gitignore
38
+ - .travis.yml
38
39
  - Gemfile
39
40
  - LICENSE.txt
40
41
  - README.md