mongoid_silo 0.0.7 → 0.1.0

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/.rspec ADDED
@@ -0,0 +1,5 @@
1
+ --color
2
+ --require rspec/instafail
3
+ --format RSpec::Instafail
4
+ --fail-fast
5
+ --drb
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.3"
4
+ services: mongodb
5
+ script: bundle exec rspec spec
data/Gemfile CHANGED
@@ -2,3 +2,23 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in mongoid-silo.gemspec
4
4
  gemspec
5
+
6
+ group :test do
7
+ gem 'rspec'
8
+ gem 'factory_girl'
9
+ gem 'database_cleaner'
10
+ gem 'fuubar'
11
+ gem 'faker'
12
+ gem 'spork'
13
+ end
14
+
15
+ group :development do
16
+ gem 'guard'
17
+ gem 'terminal-notifier-guard'
18
+ gem 'guard-rspec'
19
+ gem 'guard-spork'
20
+ gem 'guard-bundler'
21
+ gem 'rb-inotify', :require => false
22
+ gem 'rb-fsevent', :require => false
23
+ gem 'rb-fchange', :require => false
24
+ end
data/Guardfile ADDED
@@ -0,0 +1,13 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :bundler do
5
+ watch("Gemfile")
6
+ end
7
+
8
+ guard :rspec do
9
+ watch(%r{^app/models/(.+)\.rb$}) { |m| "spec/models/#{m[1]}_spec.rb" }
10
+ watch(%r{^app/workers/(.+)\.rb$}) { "spec" }
11
+ watch(%r{^spec/.+_spec\.rb$})
12
+ watch('spec/spec_helper.rb') { "spec" }
13
+ end
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/musicglue/mongoid_silo)
1
+ [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/musicglue/mongoid_silo) [![Build Status](https://travis-ci.org/musicglue/mongoid_silo.png?branch=master)](https://travis-ci.org/musicglue/mongoid_silo)
2
2
  # MongoidSilo
3
3
 
4
4
  MongoidSilo creates and transparently manages static representations of a model - e.g. for creating Feeds or other diverse datastructures.
@@ -27,12 +27,28 @@ Include ```Mongoid::Silo``` in your model, and then declare your silos.
27
27
 
28
28
  ```ruby
29
29
  # The default usage creates a "default" silo, accessable through instance#default_silo that will call
30
- # an instance#to_silo method to populate itself on save.
30
+ # down to the default 'GrainBelt' generator. This will simply store all the attributes on your model,
31
+ # so you almost certainly don't want this. See below for more details.
31
32
  silo
32
33
 
33
- # Or you can specify the silo name and the method that will be called to populate it, like so...
34
- silo :feed, :make_my_feed
34
+ # Or you can specify the silo name and the class that will be called to populate it, like so...
35
+ silo :feed, generator: "MyGeneratorClass"
36
+
37
+ # To create a custom generator class, simply inherit from MongoidSilo::GrainBelt and override the
38
+ # generate method.
39
+ class MyGeneratorClass < MongoidSilo::GrainBelt
40
+ def generate
41
+ {
42
+ name: name,
43
+ age: age,
44
+ dingbats: true
45
+ }
46
+ end
47
+ end
35
48
  ```
49
+ The generator class gets passed the instance of your model when the Silo is generated, and it exposes
50
+ your methods and attributes on that instance. Otherwise, you have access to the instance through the ```object``` accessor.
51
+
36
52
 
37
53
  ## Contributing
38
54
 
@@ -5,33 +5,51 @@ module MongoidSilo
5
5
  class UpdateSiloWorker
6
6
  include Sidekiq::Worker
7
7
 
8
- def perform(item_id, item_class, name, mode="save", method=nil)
9
- @item_id, @item_class = item_id, item_class
8
+ def perform(item_id, item_class, name, mode="save", generator=nil)
9
+ @item_id, @item_class, @generator = item_id, item_class, generator
10
10
 
11
- mode.to_s == "save" ? update_silo(name, method) : destroy_silo(name)
11
+ mode.to_s == "save" ? update_silo(name, generator) : destroy_silo(name)
12
12
  end
13
13
 
14
14
 
15
15
  private
16
- def update_silo name, method
17
- puts "[SILO] Creating or Updating Silo for #{@item_class}::::#{@item_id}"
18
- @item = @item_class.classify.constantize.send(:find, @item_id)
16
+ def update_silo name, generator
17
+ @item = item_class.send(:find, @item_id)
19
18
  @silo = Silo.where(item_class: @item_class, item_id: @item_id, silo_type: name).first
19
+ @content = generator_class.send(:new, @item).generate
20
20
  if @silo
21
- @silo.set(:bag, @item.send(method))
21
+ @silo.set(:bag, @content)
22
22
  else
23
- @silo = Silo.create(item_class: @item_class, item_id: @item_id, bag: @item.send(method), silo_type: name)
23
+ @silo = Silo.create(item_class: @item_class, item_id: @item_id, bag: @content, silo_type: name)
24
24
  end
25
25
  end
26
26
 
27
27
  def destroy_silo name
28
- puts "[SILO] Destroying Silo for #{@item_class}::::#{@item_id}"
29
28
  @silo = Silo.where(item_class: @item_class, item_id: @item_id, silo_type: name).first
30
29
  if @silo
31
30
  @silo.destroy
32
31
  end
33
32
  end
34
33
 
34
+ def item_class
35
+ cl = nil
36
+ @item_class.split("::").inject(nil) do |parent, identifier|
37
+ parent ||= Kernel
38
+ cl = parent.const_get(identifier)
39
+ end
40
+ cl
41
+ end
42
+
43
+
44
+ def generator_class
45
+ cl = nil
46
+ @generator.split("::").inject(nil) do |parent, identifier|
47
+ parent ||= Kernel
48
+ cl = parent.const_get(identifier)
49
+ end
50
+ cl
51
+ end
52
+
35
53
  end
36
54
 
37
55
  end
data/lib/mongoid/silo.rb CHANGED
@@ -5,13 +5,14 @@ module Mongoid
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  module ClassMethods
8
- def silo name=:default, method=:to_silo
8
+ def silo name=:default, opts={}
9
+ opts[:generator] ||= "MongoidSilo::GrainBelt"
9
10
  define_method "#{name}_silo" do
10
11
  from_silo name
11
12
  end
12
13
 
13
14
  set_callback :save, :after do
14
- update_silo name, method
15
+ update_silo name, opts[:generator]
15
16
  end
16
17
 
17
18
  set_callback :destroy, :after do
@@ -20,36 +21,30 @@ module Mongoid
20
21
  end
21
22
  end
22
23
 
23
- module InstanceMethods
24
- def update_silo name, method
25
- MongoidSilo::UpdateSiloWorker.perform_async(self.id.to_s, self.class.to_s, name, :save, method)
26
- end
27
-
28
- def destroy_silo name
29
- MongoidSilo::UpdateSiloWorker.perform_async(self.id.to_s, self.class.to_s, name, :destroy)
30
- end
24
+ def update_silo name, generator
25
+ MongoidSilo::UpdateSiloWorker.perform_async(self.id.to_s, self.class.to_s, name, :save, generator)
26
+ end
31
27
 
32
- def to_silo #OVERWRITE THIS IN YOUR MODELS, BITCHES
33
- {}
34
- end
28
+ def destroy_silo name
29
+ MongoidSilo::UpdateSiloWorker.perform_async(self.id.to_s, self.class.to_s, name, :destroy)
30
+ end
35
31
 
36
- def from_silo name="default"
37
- if @bag && @bag[name]
38
- @bag[name]
39
- else
40
- @bag = {}
41
- @bag[name] ||= begin
42
- silo = ::Silo.where(item_class: self.class.to_s, item_id: self.id.to_s, silo_type: name).first
43
- silo.bag
44
- rescue Mongoid::Errors::DocumentNotFound
45
- {}
46
- end
32
+ def from_silo name="default"
33
+ if @bag && @bag[name]
34
+ @bag[name]
35
+ else
36
+ @bag = {}
37
+ @bag[name] ||= begin
38
+ silo = ::Silo.where(item_class: self.class.to_s, item_id: self.id.to_s, silo_type: name).first
39
+ silo.bag
40
+ rescue Mongoid::Errors::DocumentNotFound
41
+ {}
47
42
  end
48
43
  end
44
+ end
49
45
 
50
- def json_from_silo
51
- MultiJson.encode from_silo
52
- end
46
+ def json_from_silo
47
+ MultiJson.encode from_silo
53
48
  end
54
49
  end
55
50
  end
@@ -0,0 +1,22 @@
1
+ module MongoidSilo
2
+ class GrainBelt
3
+
4
+ attr_accessor :object
5
+
6
+ def initialize(object)
7
+ @object = object
8
+ end
9
+
10
+ def method_missing(meth, *args)
11
+ object.send(meth)
12
+ end
13
+
14
+ def generate
15
+ out = {}
16
+ object.attribute_names.each do |attribute|
17
+ out[attribute] = object.send(attribute) unless ["_type", "_id"].include?(attribute)
18
+ end
19
+ out
20
+ end
21
+ end
22
+ end
@@ -1,3 +1,3 @@
1
1
  module MongoidSilo
2
- VERSION = "0.0.7"
2
+ VERSION = "0.1.0"
3
3
  end
data/lib/mongoid_silo.rb CHANGED
@@ -1,8 +1,9 @@
1
1
  require "mongoid_silo/version"
2
2
  require 'mongoid_silo/railtie' if defined?(Rails)
3
+ require 'mongoid_silo/grain_belt'
3
4
  require 'mongoid/silo'
4
- require_relative '../app/models/silo'
5
- require_relative '../app/workers/mongoid_silo/update_silo_worker'
5
+
6
+ Dir['./app/**/*.rb'].each{ |file| require file }
6
7
 
7
8
  module MongoidSilo
8
9
  end
@@ -0,0 +1,6 @@
1
+ FactoryGirl.define do
2
+ factory :complex_project do
3
+ name { Faker::Name.name }
4
+ due_date { DateTime.now }
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ FactoryGirl.define do
2
+ factory :multi_silo_project do
3
+ name { Faker::Name.name }
4
+ city { Faker::Address.city }
5
+ country { Faker::Address.country }
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ FactoryGirl.define do
2
+ factory :project do
3
+ name { Faker::Name.name }
4
+ end
5
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe MongoidSilo::GrainBelt do
4
+ context "Instantiated with a simple model" do
5
+
6
+ before do
7
+ @model = create(:project)
8
+ @silovator = MongoidSilo::GrainBelt.new(@model)
9
+ end
10
+
11
+ it "exposes the model's properties without prefixing" do
12
+ @silovator.name.should eq(@model.name)
13
+ end
14
+
15
+ it "exposes the model through the object accessor" do
16
+ @silovator.object.should eq(@model)
17
+ end
18
+
19
+ it "generates a hash for storing in the silo" do
20
+ @silovator.generate.should be_a(Hash)
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,132 @@
1
+ require 'spec_helper'
2
+
3
+ describe Silo do
4
+
5
+ context 'simple silos' do
6
+ before do
7
+ @project = create(:project)
8
+ end
9
+
10
+ it "should persist a Silo" do
11
+ @project.should be_persisted
12
+ Silo.count.should eq(1)
13
+ end
14
+
15
+ it "should contain the name of the project" do
16
+ @project.default_silo.should eq({"name" => @project.name})
17
+ end
18
+
19
+ it "should update the name if the name changes" do
20
+ @project.name = Faker::Name.name
21
+ @project.save
22
+ @project.default_silo["name"].should eq(@project.name)
23
+ end
24
+
25
+ it "should delete the silo if the project is deleted" do
26
+ @project.destroy
27
+ Silo.count.should eq(0)
28
+ end
29
+
30
+ end
31
+
32
+ context 'Direct finders and methods:' do
33
+ before do
34
+ @project1 = create(:project)
35
+ @project2 = create(:project)
36
+ @project3 = create(:complex_project)
37
+ end
38
+
39
+ it "should find by id and silo type" do
40
+ found = Silo.for_id_and_name_with_no_class(@project1.id.to_s, "default")
41
+ found.should_not be_nil
42
+ end
43
+
44
+ it "should find by id and class and silo type" do
45
+ found = Silo.for_id_and_class_with_name(@project1.id.to_s, @project1.class.to_s, "default")
46
+ found.should_not be_nil
47
+ end
48
+
49
+ it "should find complex documents" do
50
+ found = Silo.for_id_and_class_with_name(@project3.id.to_s, @project3.class.to_s, "complex")
51
+ found.should_not be_nil
52
+ end
53
+
54
+ it "should not find where no match exists" do
55
+ found = Silo.for_id_and_class_with_name("wombats", "aren't", "real")
56
+ found.should be_nil
57
+ end
58
+
59
+ it "should serialize to JSON correctly" do
60
+ found = Silo.for_id_and_class_with_name(@project1.id.to_s, @project1.class.to_s, "default")
61
+ MultiJson.decode("#{found.to_json}").should be_a(Hash)
62
+ end
63
+ end
64
+
65
+ context "Custom Silo constructors:" do
66
+ before do
67
+ @complex_project = create(:complex_project)
68
+ end
69
+
70
+ it "defines an accessor based on the declared silo name" do
71
+ @complex_project.should respond_to(:complex_silo)
72
+ end
73
+
74
+ it "updates a silo on save" do
75
+ @complex_project.name = Faker::Name.name
76
+ @complex_project.save
77
+ @complex_project.complex_silo["name"].should eq(@complex_project.name)
78
+ end
79
+
80
+ it "removes the custom silo on destroying the project" do
81
+ @complex_project.destroy
82
+ Silo.count.should eq(0)
83
+ end
84
+ end
85
+
86
+ context "Multiple silo constructors:" do
87
+ before do
88
+ @multi_silo_project = create(:multi_silo_project)
89
+ end
90
+
91
+ it "Creates two silos" do
92
+ Silo.count.should eq(2)
93
+ end
94
+
95
+ it "Correctly populates the Name silo" do
96
+ _expectation = {
97
+ "name" => @multi_silo_project.name
98
+ }
99
+ @multi_silo_project.name_silo.should eq(_expectation)
100
+ end
101
+
102
+ it "Correctly populates the Location silo" do
103
+ _expectation = {
104
+ "city" => @multi_silo_project.city,
105
+ "country" => @multi_silo_project.country
106
+ }
107
+ @multi_silo_project.location_silo.should eq(_expectation)
108
+ end
109
+
110
+ it "Correctly updates both silos" do
111
+ @multi_silo_project.city = Faker::Address.city
112
+ @multi_silo_project.country = Faker::Address.country
113
+ @multi_silo_project.name = Faker::Name.name
114
+ @multi_silo_project.save
115
+ _name_silo_expectation = {
116
+ "name" => @multi_silo_project.name
117
+ }
118
+ _location_silo_expectation = {
119
+ "city" => @multi_silo_project.city,
120
+ "country" => @multi_silo_project.country
121
+ }
122
+ @multi_silo_project.name_silo.should eq(_name_silo_expectation)
123
+ @multi_silo_project.location_silo.should eq(_location_silo_expectation)
124
+ end
125
+
126
+ it "Destroys both silos when project is deleted" do
127
+ @multi_silo_project.destroy
128
+ Silo.count.should eq(0)
129
+ end
130
+ end
131
+
132
+ end
data/spec/mongoid.yml ADDED
@@ -0,0 +1,9 @@
1
+ test:
2
+ sessions:
3
+ default:
4
+ hosts:
5
+ - localhost:27017
6
+ database: mongoid_silo-test
7
+ options:
8
+ identity_map_enabled: false
9
+ safe: false
@@ -0,0 +1,50 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'spork'
4
+ require 'guard/rspec'
5
+ require 'rspec'
6
+
7
+ Spork.prefork do
8
+ require 'mongoid_silo'
9
+ require 'factory_girl'
10
+ require 'database_cleaner'
11
+ require 'faker'
12
+ require 'sidekiq/testing/inline'
13
+ # Loading more in this block will cause your tests to run faster. However,
14
+ # if you change any configuration or code from libraries loaded here, you'll
15
+ # need to restart spork for it take effect.
16
+ FactoryGirl.find_definitions
17
+
18
+ Mongoid.load!(File.expand_path("../mongoid.yml", __FILE__), :test)
19
+
20
+
21
+
22
+ RSpec.configure do |config|
23
+ config.include FactoryGirl::Syntax::Methods
24
+
25
+ config.before(:suite) do
26
+ DatabaseCleaner.strategy = :truncation
27
+ DatabaseCleaner.clean
28
+ end
29
+
30
+ config.after(:each) do
31
+ DatabaseCleaner.clean
32
+ end
33
+ end
34
+
35
+ Dir['./spec/support/**/*.rb'].each{ |file| require file }
36
+ end
37
+
38
+ Spork.each_run do
39
+ Dir['./app/**/*.rb'].each { |file| require file }
40
+ end
41
+
42
+
43
+
44
+
45
+
46
+
47
+
48
+
49
+
50
+
@@ -0,0 +1,11 @@
1
+ class ComplexProject
2
+ include Mongoid::Document
3
+ include Mongoid::Silo
4
+
5
+ field :name, type: String
6
+ field :due_date, type: DateTime
7
+
8
+
9
+ silo :complex, generator: "MakeComplexGrainBelt"
10
+
11
+ end
@@ -0,0 +1,12 @@
1
+ class MultiSiloProject
2
+ include Mongoid::Document
3
+ include Mongoid::Silo
4
+
5
+ field :name, type: String
6
+ field :city, type: String
7
+ field :country, type: String
8
+
9
+ silo :name, generator: "MakeNameGrainBelt"
10
+ silo :location, generator: "MakeLocationGrainBelt"
11
+
12
+ end
@@ -0,0 +1,9 @@
1
+ class Project
2
+ include Mongoid::Document
3
+ include Mongoid::Silo
4
+
5
+ field :name, type: String
6
+
7
+ silo
8
+
9
+ end
@@ -0,0 +1,8 @@
1
+ class MakeComplexGrainBelt < MongoidSilo::GrainBelt
2
+ def generate
3
+ {
4
+ name: name,
5
+ due_date: due_date
6
+ }
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ class MakeLocationGrainBelt < MongoidSilo::GrainBelt
2
+ def generate
3
+ {
4
+ city: city,
5
+ country: country
6
+ }
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ class MakeNameGrainBelt < MongoidSilo::GrainBelt
2
+ def generate
3
+ {
4
+ name: name
5
+ }
6
+ end
7
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid_silo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.1.0
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: 2013-01-03 00:00:00.000000000 Z
12
+ date: 2013-01-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -67,7 +67,10 @@ extensions: []
67
67
  extra_rdoc_files: []
68
68
  files:
69
69
  - .gitignore
70
+ - .rspec
71
+ - .travis.yml
70
72
  - Gemfile
73
+ - Guardfile
71
74
  - LICENSE.txt
72
75
  - README.md
73
76
  - Rakefile
@@ -75,9 +78,23 @@ files:
75
78
  - app/workers/mongoid_silo/update_silo_worker.rb
76
79
  - lib/mongoid/silo.rb
77
80
  - lib/mongoid_silo.rb
81
+ - lib/mongoid_silo/grain_belt.rb
78
82
  - lib/mongoid_silo/railtie.rb
79
83
  - lib/mongoid_silo/version.rb
80
84
  - mongoid_silo.gemspec
85
+ - spec/factories/complex_project_factory.rb
86
+ - spec/factories/multi_silo_project_factory.rb
87
+ - spec/factories/project_factory.rb
88
+ - spec/lib/grain_belt_spec.rb
89
+ - spec/models/silo_spec.rb
90
+ - spec/mongoid.yml
91
+ - spec/spec_helper.rb
92
+ - spec/support/models/complex_project.rb
93
+ - spec/support/models/multi_silo_project.rb
94
+ - spec/support/models/project.rb
95
+ - spec/support/silovators/make_complex_grain_belt.rb
96
+ - spec/support/silovators/make_location_grain_belt.rb
97
+ - spec/support/silovators/make_name_grain_belt.rb
81
98
  homepage: https://github.com/musicglue/mongoid_silo
82
99
  licenses: []
83
100
  post_install_message:
@@ -102,5 +119,18 @@ rubygems_version: 1.8.24
102
119
  signing_key:
103
120
  specification_version: 3
104
121
  summary: MongoidSilo is a bit like a Grain Elevator, but without the grain.
105
- test_files: []
122
+ test_files:
123
+ - spec/factories/complex_project_factory.rb
124
+ - spec/factories/multi_silo_project_factory.rb
125
+ - spec/factories/project_factory.rb
126
+ - spec/lib/grain_belt_spec.rb
127
+ - spec/models/silo_spec.rb
128
+ - spec/mongoid.yml
129
+ - spec/spec_helper.rb
130
+ - spec/support/models/complex_project.rb
131
+ - spec/support/models/multi_silo_project.rb
132
+ - spec/support/models/project.rb
133
+ - spec/support/silovators/make_complex_grain_belt.rb
134
+ - spec/support/silovators/make_location_grain_belt.rb
135
+ - spec/support/silovators/make_name_grain_belt.rb
106
136
  has_rdoc: