mongoid-embedded-errors 1.0.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/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.log
2
+ .DS_Store
3
+ doc
4
+ tmp
5
+ pkg
6
+ *.gem
7
+ *.pid
8
+ coverage
9
+ coverage.data
10
+ build/*
11
+ *.pbxuser
12
+ *.mode1v3
13
+ .svn
14
+ profile
15
+ .console_history
16
+ .sass-cache/*
17
+ .rake_tasks~
18
+ *.log.lck
19
+ solr/
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mongoid_delorean.gemspec
4
+ gemspec
5
+
6
+ gem "rspec"
7
+ gem 'database_cleaner'
data/Gemfile.lock ADDED
@@ -0,0 +1,44 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ mongoid-embedded-errors (1.0.0)
5
+ mongoid (>= 3.0.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activemodel (3.2.8)
11
+ activesupport (= 3.2.8)
12
+ builder (~> 3.0.0)
13
+ activesupport (3.2.8)
14
+ i18n (~> 0.6)
15
+ multi_json (~> 1.0)
16
+ builder (3.0.4)
17
+ database_cleaner (0.9.1)
18
+ diff-lcs (1.1.3)
19
+ i18n (0.6.1)
20
+ mongoid (3.0.9)
21
+ activemodel (~> 3.1)
22
+ moped (~> 1.1)
23
+ origin (~> 1.0)
24
+ tzinfo (~> 0.3.22)
25
+ moped (1.2.7)
26
+ multi_json (1.3.6)
27
+ origin (1.0.9)
28
+ rspec (2.11.0)
29
+ rspec-core (~> 2.11.0)
30
+ rspec-expectations (~> 2.11.0)
31
+ rspec-mocks (~> 2.11.0)
32
+ rspec-core (2.11.1)
33
+ rspec-expectations (2.11.3)
34
+ diff-lcs (~> 1.1.3)
35
+ rspec-mocks (2.11.3)
36
+ tzinfo (0.3.33)
37
+
38
+ PLATFORMS
39
+ ruby
40
+
41
+ DEPENDENCIES
42
+ database_cleaner
43
+ mongoid-embedded-errors!
44
+ rspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Mark Bates
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,98 @@
1
+ # Mongoid::EmbeddedErrors
2
+
3
+ Easily bubble up errors from embedded documents in Mongoid.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'mongoid-embedded-errors'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install mongoid-embedded-errors
18
+
19
+ ## Usage
20
+
21
+ Embedded documents in Mongoid can be really useful. However, when one of those embedded documents is invalid, Mongoid spits up completely useless errors.
22
+
23
+ Let's look an example. Here we have an `Article` which `embeds_many :pages`. A `Page` `embeds_many :sections`.
24
+
25
+ ```ruby
26
+ class Article
27
+ include Mongoid::Document
28
+
29
+ field :name, type: String
30
+ field :summary, type: String
31
+ validates :name, presence: true
32
+ validates :summary, presence: true
33
+
34
+ embeds_many :pages
35
+ end
36
+
37
+ class Page
38
+ include Mongoid::Document
39
+
40
+ field :title, type: String
41
+ validates :title, presence: true
42
+
43
+ embedded_in :article, inverse_of: :pages
44
+ embeds_many :sections
45
+ end
46
+
47
+ class Section
48
+ include Mongoid::Document
49
+
50
+ field :header, type: String
51
+ field :body, type: String
52
+ validates :header, presence: true
53
+
54
+ embedded_in :page, inverse_of: :sections
55
+ end
56
+ ```
57
+
58
+ If we were to create an invalid `Article` with an invalid `Page` and tried to validate it the errors we see would not be very helpful:
59
+
60
+ ```ruby
61
+ article = Article.new(pages: [Page.new])
62
+ article.valid? # => false
63
+
64
+ article.error.messages
65
+ # => {:name=>["can't be blank"], :summary=>["can't be blank"], :pages=>["is invalid"]}
66
+ ```
67
+
68
+ Why was the `Page` invalid? Who knows! But, if we include the `Mongoid::EmbeddedErrors` module we get much better error messaging:
69
+
70
+ ```ruby
71
+ class Article
72
+ include Mongoid::Document
73
+ include Mongoid::EmbeddedErrors
74
+
75
+ field :name, type: String
76
+ field :summary, type: String
77
+ validates :name, presence: true
78
+ validates :summary, presence: true
79
+
80
+ embeds_many :pages
81
+ end
82
+
83
+ article = Article.new(pages: [Page.new(sections: [Section.new])])
84
+ article.valid? # => false
85
+
86
+ article.error.messages
87
+ # => {:name=>["can't be blank"], :summary=>["can't be blank"], :pages=>[{"5086ec0d421aa94f0f000002"=>{:title=>["can't be blank"], :sections=>[{"5086ec0d421aa94f0f000001"=>{:header=>["can't be blank"]}}]}}]}
88
+ ```
89
+
90
+ Now, isn't that much nicer? Yeah, I think so to.
91
+
92
+ ## Contributing
93
+
94
+ 1. Fork it
95
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
96
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
97
+ 4. Push to the branch (`git push origin my-new-feature`)
98
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ desc "Run tests"
5
+ task :default => [:ruby]
6
+
7
+ task :ruby do
8
+ system "bundle exec rspec"
9
+ end
@@ -0,0 +1,16 @@
1
+ require "mongoid/relations/embedded/in"
2
+
3
+ module Mongoid
4
+ module Relations
5
+ module Macros
6
+ module ClassMethods
7
+ alias :embedded_in_without_embedded_errors :embedded_in
8
+ def embedded_in(*args)
9
+ relation = embedded_in_without_embedded_errors(*args)
10
+ self.send(:include, Mongoid::EmbeddedErrors)
11
+ return relation
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ module Mongoid
2
+ module EmbeddedErrors
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,26 @@
1
+ require 'mongoid'
2
+ require "mongoid-embedded-errors/version"
3
+ require "mongoid-embedded-errors/embedded_in"
4
+
5
+ module Mongoid
6
+ module EmbeddedErrors
7
+
8
+ def self.included(klass)
9
+ klass.alias_method_chain(:errors, :embedded_errors)
10
+ end
11
+
12
+ def errors_with_embedded_errors
13
+ errs = errors_without_embedded_errors
14
+ self.embedded_relations.each do |name, metadata|
15
+ if errs[name]
16
+ errs.delete(name.to_sym)
17
+ self.send(name).each do |rel|
18
+ errs[name] = {rel.id.to_s => rel.errors.messages} if rel.errors.any?
19
+ end
20
+ end
21
+ end
22
+ return errs
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mongoid-embedded-errors/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "mongoid-embedded-errors"
8
+ gem.version = Mongoid::EmbeddedErrors::VERSION
9
+ gem.authors = ["Mark Bates"]
10
+ gem.email = ["mark@markbates.com"]
11
+ gem.description = %q{Easily bubble up errors from embedded documents in Mongoid.}
12
+ gem.summary = %q{Easily bubble up errors from embedded documents in Mongoid.}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency("mongoid", ">=3.0.0")
21
+ end
data/spec/config.yml ADDED
@@ -0,0 +1,6 @@
1
+ test:
2
+ sessions:
3
+ default:
4
+ database: mongoid_embedded_errors_test
5
+ hosts:
6
+ - localhost:27017
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongoid::EmbeddedErrors do
4
+
5
+ let(:article) { Article.new }
6
+ let(:invalid_page) { Page.new }
7
+ let(:invalid_section) { Section.new }
8
+ let(:valid_section) { Section.new(header: "My Header") }
9
+
10
+ describe "errors" do
11
+
12
+ it "bubbles up errors from embedded documents" do
13
+ invalid_page.sections << invalid_section
14
+ article.pages << invalid_page
15
+ article.should_not be_valid
16
+ puts article.errors.messages
17
+ article.errors.messages.should eql({
18
+ name: ["can't be blank"],
19
+ summary: ["can't be blank"],
20
+ pages: [{
21
+ invalid_page.id.to_s => {
22
+ title: ["can't be blank"],
23
+ sections: [{
24
+ invalid_section.id.to_s => {
25
+ header: ["can't be blank"]
26
+ }
27
+ }]
28
+ }
29
+ }]
30
+ })
31
+ end
32
+
33
+ it "save works as before" do
34
+ article.save.should be_false
35
+ article.should_not be_persisted
36
+ article.errors.messages.should eql(name: ["can't be blank"], summary: ["can't be blank"])
37
+ end
38
+
39
+ it "handles errors on the main object" do
40
+ article.should_not be_valid
41
+ article.errors.messages.should eql(name: ["can't be blank"], summary: ["can't be blank"])
42
+ end
43
+
44
+ end
45
+
46
+ end
@@ -0,0 +1,18 @@
1
+ require 'bundler/setup'
2
+
3
+ require 'mongoid-embedded-errors' # and any other gems you need
4
+
5
+ require 'database_cleaner'
6
+
7
+ Mongoid.load!(File.join(File.dirname(__FILE__), "config.yml"), :test)
8
+ require File.join(File.dirname(__FILE__), "support", "models")
9
+
10
+ DatabaseCleaner[:mongoid].strategy = :truncation
11
+
12
+ RSpec.configure do |config|
13
+
14
+ config.before(:each) do
15
+ DatabaseCleaner.clean
16
+ end
17
+
18
+ end
@@ -0,0 +1,37 @@
1
+ class Article
2
+ include Mongoid::Document
3
+ include Mongoid::Timestamps
4
+ include Mongoid::EmbeddedErrors
5
+
6
+ field :name, type: String
7
+ field :summary, type: String
8
+
9
+ validates :name, presence: true
10
+ validates :summary, presence: true
11
+
12
+ embeds_many :pages
13
+ end
14
+
15
+ class Page
16
+ include Mongoid::Document
17
+ include Mongoid::Timestamps
18
+
19
+ field :title, type: String
20
+
21
+ validates :title, presence: true
22
+
23
+ embedded_in :article, inverse_of: :pages
24
+ embeds_many :sections
25
+ end
26
+
27
+ class Section
28
+ include Mongoid::Document
29
+ include Mongoid::Timestamps
30
+
31
+ field :header, type: String
32
+ field :body, type: String
33
+
34
+ validates :header, presence: true
35
+
36
+ embedded_in :page, inverse_of: :sections
37
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongoid-embedded-errors
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mark Bates
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mongoid
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 3.0.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 3.0.0
30
+ description: Easily bubble up errors from embedded documents in Mongoid.
31
+ email:
32
+ - mark@markbates.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - .gitignore
38
+ - Gemfile
39
+ - Gemfile.lock
40
+ - LICENSE.txt
41
+ - README.md
42
+ - Rakefile
43
+ - lib/mongoid-embedded-errors.rb
44
+ - lib/mongoid-embedded-errors/embedded_in.rb
45
+ - lib/mongoid-embedded-errors/version.rb
46
+ - mongoid-embedded-errors.gemspec
47
+ - spec/config.yml
48
+ - spec/embedded_errors_spec.rb
49
+ - spec/spec_helper.rb
50
+ - spec/support/models.rb
51
+ homepage: ''
52
+ licenses: []
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ requirements: []
70
+ rubyforge_project:
71
+ rubygems_version: 1.8.24
72
+ signing_key:
73
+ specification_version: 3
74
+ summary: Easily bubble up errors from embedded documents in Mongoid.
75
+ test_files:
76
+ - spec/config.yml
77
+ - spec/embedded_errors_spec.rb
78
+ - spec/spec_helper.rb
79
+ - spec/support/models.rb