mongoid-embedded-errors 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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