mongoid-siblings 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/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +83 -0
- data/Rakefile +17 -0
- data/lib/mongoid/siblings.rb +202 -0
- data/spec/mongoid/siblings_spec.rb +679 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/support/models.rb +49 -0
- metadata +96 -0
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Douwe Maan
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# mongoid-siblings
|
2
|
+
|
3
|
+
mongoid-siblings adds methods to enable you to easily access your Mongoid
|
4
|
+
document's siblings.
|
5
|
+
|
6
|
+
## Requirements
|
7
|
+
|
8
|
+
* mongoid (~> 3.0)
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add the following to your Gemfile:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
gem "mongoid-siblings"
|
16
|
+
```
|
17
|
+
|
18
|
+
And tell Bundler to install the new gem:
|
19
|
+
|
20
|
+
```
|
21
|
+
bundle install
|
22
|
+
```
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
Include the `Mongoid::Siblings` module in your document class:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
class Book
|
30
|
+
include Mongoid::Document
|
31
|
+
include Mongoid::Siblings
|
32
|
+
|
33
|
+
belongs_to :publisher
|
34
|
+
belongs_to :author
|
35
|
+
|
36
|
+
...
|
37
|
+
end
|
38
|
+
```
|
39
|
+
|
40
|
+
You will now have access to the following methods:
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
# Find all books by this book's author, not including this book.
|
44
|
+
book.siblings(scope: :author)
|
45
|
+
|
46
|
+
# Find all books by this book's author.
|
47
|
+
book.siblings_and_self(scope: :author)
|
48
|
+
|
49
|
+
# Check whether a certain book was published by the same publisher as this book.
|
50
|
+
book.sibling_of?(other_book, scope: :publisher)
|
51
|
+
|
52
|
+
# Make this book a sibling of a book with another author and publisher.
|
53
|
+
# This will set this books author and publisher to match that of the other book.
|
54
|
+
book.sibling_of!(other_book, scope: [:author, :publisher])
|
55
|
+
```
|
56
|
+
|
57
|
+
## Full documentation
|
58
|
+
See [this project's RubyDoc.info page](http://rubydoc.info/github/DouweM/mongoid-siblings/master/frames).
|
59
|
+
|
60
|
+
## Known issues
|
61
|
+
See [the GitHub Issues page](https://github.com/DouweM/mongoid-siblings/issues).
|
62
|
+
|
63
|
+
## License
|
64
|
+
Copyright (c) 2012 Douwe Maan
|
65
|
+
|
66
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
67
|
+
a copy of this software and associated documentation files (the
|
68
|
+
"Software"), to deal in the Software without restriction, including
|
69
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
70
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
71
|
+
permit persons to whom the Software is furnished to do so, subject to
|
72
|
+
the following conditions:
|
73
|
+
|
74
|
+
The above copyright notice and this permission notice shall be
|
75
|
+
included in all copies or substantial portions of the Software.
|
76
|
+
|
77
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
78
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
79
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
80
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
81
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
82
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
83
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "rspec/core/rake_task"
|
2
|
+
|
3
|
+
spec = Gem::Specification.load("mongoid-siblings.gemspec")
|
4
|
+
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
6
|
+
|
7
|
+
task default: :spec
|
8
|
+
|
9
|
+
desc "Build the .gem file"
|
10
|
+
task :build do
|
11
|
+
system "gem build #{spec.name}.gemspec"
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Push the .gem file to rubygems.org"
|
15
|
+
task release: :build do
|
16
|
+
system "gem push #{spec.name}-#{spec.version}.gem"
|
17
|
+
end
|
@@ -0,0 +1,202 @@
|
|
1
|
+
module Mongoid
|
2
|
+
|
3
|
+
# Adds methods to easily access your document's siblings.
|
4
|
+
module Siblings
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
cattr_accessor :default_sibling_scope
|
9
|
+
end
|
10
|
+
|
11
|
+
# Returns this document's siblings.
|
12
|
+
#
|
13
|
+
# @example Retrieve document's siblings
|
14
|
+
# book.siblings
|
15
|
+
#
|
16
|
+
# @see {#siblings_and_self}
|
17
|
+
def siblings(options = {})
|
18
|
+
self.siblings_and_self(options).excludes(id: self.id)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns this document's siblings and itself.
|
22
|
+
#
|
23
|
+
# @example Retrieve document's siblings and itself within a certain scope.
|
24
|
+
# book.siblings_and_self(scope: :author)
|
25
|
+
#
|
26
|
+
# @example Retrieve what would be document's siblings if it had another scope value.
|
27
|
+
#
|
28
|
+
# book.siblings_and_self(
|
29
|
+
# scope: :author,
|
30
|
+
# scope_values: {
|
31
|
+
# author: other_author
|
32
|
+
# }
|
33
|
+
# )
|
34
|
+
#
|
35
|
+
# @param [ Hash ] options The options.
|
36
|
+
#
|
37
|
+
# @option options [ Array<Symbol>, Symbol ] scope One or more relations or
|
38
|
+
# attributes that siblings of this object need to have in common.
|
39
|
+
# @option options [ Hash<Symbol, Object> ] scope_values Optional alternative
|
40
|
+
# values to use to determine siblingship.
|
41
|
+
#
|
42
|
+
# @return [ Mongoid::Criteria ] Criteria to retrieve the document's siblings.
|
43
|
+
def siblings_and_self(options = {})
|
44
|
+
scopes = options[:scope] || self.default_sibling_scope
|
45
|
+
scope_values = options[:scope_values] || {}
|
46
|
+
|
47
|
+
scopes = Array.wrap(scopes).compact
|
48
|
+
|
49
|
+
|
50
|
+
criteria = base_document_class.all
|
51
|
+
|
52
|
+
detail_scopes = []
|
53
|
+
|
54
|
+
# Find out what scope determines the root criteria. This can be
|
55
|
+
# [klass].all or self.[relation].
|
56
|
+
# It is assumed that for `scopes: [:rel1, :rel2]`, sibling objects always
|
57
|
+
# have the same `rel1` *and* `rel2`, and that two objects with the same
|
58
|
+
# `rel1` will always have the same `rel2`.
|
59
|
+
scopes.reverse_each do |scope|
|
60
|
+
scope_value = scope_values.fetch(scope) { self.send(scope) }
|
61
|
+
|
62
|
+
relation_metadata = self.reflect_on_association(scope)
|
63
|
+
if relation_metadata && scope_value
|
64
|
+
proxy = self.siblings_through_relation(scope, scope_value)
|
65
|
+
next if proxy.nil?
|
66
|
+
criteria = proxy.criteria
|
67
|
+
else
|
68
|
+
detail_scopes << scope
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Apply detail criteria, to make sure siblings share every simple
|
73
|
+
# attribute or nil-relation.
|
74
|
+
detail_scopes.each do |scope|
|
75
|
+
scope_value = scope_values.fetch(scope) { self.send(scope) }
|
76
|
+
|
77
|
+
relation_metadata = self.reflect_on_association(scope)
|
78
|
+
scope_key = relation_metadata ? relation_metadata.key : scope
|
79
|
+
|
80
|
+
criteria = criteria.where(scope_key => scope_value)
|
81
|
+
end
|
82
|
+
|
83
|
+
criteria
|
84
|
+
end
|
85
|
+
|
86
|
+
# Is this document a sibling of the other document?
|
87
|
+
#
|
88
|
+
# @example Is this document a sibling of the other document?
|
89
|
+
# book.sibling_of?(other_book, scope: :author)
|
90
|
+
#
|
91
|
+
# @param [ Document ] other The document to check against.
|
92
|
+
# @param [ Hash ] options The options.
|
93
|
+
#
|
94
|
+
# @option options [ Array<Symbol>, Symbol ] scope One or more relations and
|
95
|
+
# attributes that siblings of this object need to have in common.
|
96
|
+
# @option options [ Hash<Symbol, Object> ] scope_values Optional alternative
|
97
|
+
# values for this document to use to determine siblings.
|
98
|
+
# @option options [ Hash<Symbol, Object> ] other_scope_values Optional
|
99
|
+
# alternative values for the other document to use to determine
|
100
|
+
# siblingship.
|
101
|
+
#
|
102
|
+
# @return [ Boolean ] True if the document is a sibling of the other
|
103
|
+
# document.
|
104
|
+
def sibling_of?(other, options = {})
|
105
|
+
scopes = options[:scope] || self.default_sibling_scope
|
106
|
+
scope_values = options[:scope_values] || {}
|
107
|
+
other_scope_values = options[:other_scope_values] || {}
|
108
|
+
|
109
|
+
scopes = Array.wrap(scopes).compact
|
110
|
+
|
111
|
+
|
112
|
+
return false if base_document_class != base_document_class(other)
|
113
|
+
|
114
|
+
scopes.each do |scope|
|
115
|
+
scope_value = scope_values.fetch(scope) { self.send(scope) }
|
116
|
+
other_scope_value = other_scope_values.fetch(scope) { other.send(scope) }
|
117
|
+
|
118
|
+
return false if scope_value != other_scope_value
|
119
|
+
end
|
120
|
+
|
121
|
+
true
|
122
|
+
end
|
123
|
+
|
124
|
+
# Makes this document a sibling of the other document.
|
125
|
+
#
|
126
|
+
# This is done by copying over the values used to determine siblingship
|
127
|
+
# from the other document.
|
128
|
+
#
|
129
|
+
# @example Make document a sibling of the other document.
|
130
|
+
# book.sibling_of!(book_of_other_author, scope: :author)
|
131
|
+
#
|
132
|
+
# @param [ Document ] other The document to become a sibling of.
|
133
|
+
# @param [ Hash ] options The options.
|
134
|
+
#
|
135
|
+
# @option options [ Array<Symbol>, Symbol ] scope One or more relations and
|
136
|
+
# attributes that siblings of this object need to have in common.
|
137
|
+
# @option options [ Hash<Symbol, Object> ] other_scope_values Optional
|
138
|
+
# alternative values to use to determine siblingship.
|
139
|
+
#
|
140
|
+
# @return [ Boolean ] True if the document was made a sibling of the other
|
141
|
+
# document.
|
142
|
+
def sibling_of!(other, options = {})
|
143
|
+
return true if self.sibling_of?(other, options)
|
144
|
+
|
145
|
+
scopes = options[:scope] || self.default_sibling_scope
|
146
|
+
other_scope_values = options[:other_scope_values] || {}
|
147
|
+
|
148
|
+
scopes = Array.wrap(scopes).compact
|
149
|
+
|
150
|
+
|
151
|
+
return false if base_document_class != base_document_class(other)
|
152
|
+
|
153
|
+
scopes.each do |scope|
|
154
|
+
other_scope_value = other_scope_values.fetch(scope) { other.send(scope) }
|
155
|
+
|
156
|
+
relation_metadata = self.reflect_on_association(scope)
|
157
|
+
if relation_metadata && other_scope_value
|
158
|
+
other.siblings_through_relation(scope, other_scope_value) << self
|
159
|
+
else
|
160
|
+
self.send("#{scope}=", other_scope_value)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
self.save!
|
165
|
+
end
|
166
|
+
|
167
|
+
protected
|
168
|
+
|
169
|
+
def siblings_through_relation(name, other = nil)
|
170
|
+
other ||= self.send(name)
|
171
|
+
|
172
|
+
relation_metadata = self.reflect_on_association(name)
|
173
|
+
inverses = relation_metadata.inverses(other)
|
174
|
+
|
175
|
+
return nil if inverses.nil? || inverses.empty?
|
176
|
+
|
177
|
+
if inverses.length == 1
|
178
|
+
inverse = inverses.first
|
179
|
+
elsif relation_metadata.polymorphic?
|
180
|
+
inverse = inverses.find { |inverse|
|
181
|
+
inverse == self.send(relation_metadata.inverse_of_field)
|
182
|
+
}
|
183
|
+
else
|
184
|
+
inverse = inverses.find { |inverse|
|
185
|
+
other.send(inverse).include?(self)
|
186
|
+
}
|
187
|
+
end
|
188
|
+
|
189
|
+
return nil if inverse.nil?
|
190
|
+
|
191
|
+
other.send(inverse)
|
192
|
+
end
|
193
|
+
|
194
|
+
def base_document_class(doc = self)
|
195
|
+
base_document_klass = doc.class
|
196
|
+
while base_document_klass.superclass.include?(Mongoid::Document)
|
197
|
+
base_document_klass = base_document_klass.superclass
|
198
|
+
end
|
199
|
+
base_document_klass
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
@@ -0,0 +1,679 @@
|
|
1
|
+
require "spec_helper.rb"
|
2
|
+
|
3
|
+
describe Mongoid::Siblings do
|
4
|
+
|
5
|
+
let(:parent) { DummyParentDocument.create }
|
6
|
+
|
7
|
+
describe "#siblings" do
|
8
|
+
|
9
|
+
context "when using a fallback scope" do
|
10
|
+
|
11
|
+
let(:super_parent) { DummySuperParentDocument.create }
|
12
|
+
let(:parent) { DummyParentDocument.create }
|
13
|
+
subject { DummyReferencedChildDocument.create }
|
14
|
+
let!(:main_sibling) { DummyReferencedChildDocument.create(parent: parent, super_parent: super_parent) }
|
15
|
+
let!(:fallback_sibling) { DummyReferencedChildDocument.create(super_parent: super_parent) }
|
16
|
+
let!(:ultimate_sibling) { DummyReferencedChildDocument.create }
|
17
|
+
|
18
|
+
context "when providing scope values" do
|
19
|
+
|
20
|
+
let(:old_super_parent) { DummySuperParentDocument.create }
|
21
|
+
let(:old_parent) { DummyParentDocument.create }
|
22
|
+
|
23
|
+
before(:each) do
|
24
|
+
subject.parent = parent
|
25
|
+
subject.super_parent = super_parent
|
26
|
+
subject.save
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when providing one scope value" do
|
30
|
+
|
31
|
+
let!(:old_main_sibling) { DummyReferencedChildDocument.create(parent: old_parent, super_parent: super_parent) }
|
32
|
+
|
33
|
+
it "returns the subject's siblings" do
|
34
|
+
subject.siblings(
|
35
|
+
scope: [:parent, :super_parent],
|
36
|
+
scope_values: {
|
37
|
+
parent: old_parent
|
38
|
+
}
|
39
|
+
).to_a.should eq([old_main_sibling])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "when providing multiple scope values" do
|
44
|
+
|
45
|
+
let!(:old_main_sibling) { DummyReferencedChildDocument.create(parent: old_parent, super_parent: old_super_parent) }
|
46
|
+
let!(:old_fallback_sibling) { DummyReferencedChildDocument.create(super_parent: old_super_parent) }
|
47
|
+
|
48
|
+
context "when the main sibling value was nil" do
|
49
|
+
|
50
|
+
it "returns the subject's siblings" do
|
51
|
+
subject.siblings(
|
52
|
+
scope: [:parent, :super_parent],
|
53
|
+
scope_values: {
|
54
|
+
parent: nil,
|
55
|
+
super_parent: old_super_parent
|
56
|
+
}
|
57
|
+
).to_a.should eq([old_fallback_sibling])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "when the main sibling value wasn't nil" do
|
62
|
+
|
63
|
+
it "returns the subject's siblings" do
|
64
|
+
subject.siblings(
|
65
|
+
scope: [:parent, :super_parent],
|
66
|
+
scope_values: {
|
67
|
+
parent: old_parent,
|
68
|
+
super_parent: old_super_parent
|
69
|
+
}
|
70
|
+
).to_a.should eq([old_main_sibling])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "when not providing scope values" do
|
77
|
+
|
78
|
+
context "when the document has a main scope document" do
|
79
|
+
|
80
|
+
before(:each) do
|
81
|
+
subject.parent = parent
|
82
|
+
subject.super_parent = super_parent
|
83
|
+
subject.save
|
84
|
+
end
|
85
|
+
|
86
|
+
it "returns the subject's siblings" do
|
87
|
+
subject.siblings(scope: [:parent, :super_parent]).to_a.should eq([main_sibling])
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "when the document has a fallback scope document but not a main scope document" do
|
92
|
+
|
93
|
+
before(:each) do
|
94
|
+
subject.super_parent = super_parent
|
95
|
+
subject.save
|
96
|
+
end
|
97
|
+
|
98
|
+
it "returns the subject's siblings" do
|
99
|
+
subject.siblings(scope: [:parent, :super_parent]).to_a.should eq([fallback_sibling])
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "when the document has neither a main scope document or a fallback scope document" do
|
104
|
+
|
105
|
+
it "returns the subject's siblings" do
|
106
|
+
subject.siblings(scope: [:parent, :super_parent]).to_a.should eq([ultimate_sibling])
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context "when using a single scope" do
|
113
|
+
|
114
|
+
context "when providing a scope value" do
|
115
|
+
|
116
|
+
let(:old_parent) { DummyParentDocument.create }
|
117
|
+
subject { DummyReferencedChildDocument.create(parent: parent) }
|
118
|
+
let!(:old_sibling) { DummyReferencedChildDocument.create(parent: old_parent) }
|
119
|
+
let!(:sibling) { DummyReferencedChildDocument.create(parent: parent) }
|
120
|
+
|
121
|
+
it "returns the subject's siblings" do
|
122
|
+
subject.siblings(scope: :parent, scope_values: { parent: old_parent }).to_a.should eq([old_sibling])
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "when not providing a scope value" do
|
127
|
+
|
128
|
+
context "when using a referenced relation" do
|
129
|
+
|
130
|
+
subject { DummyReferencedChildDocument.create }
|
131
|
+
|
132
|
+
context "when using a non-polymorphic relation" do
|
133
|
+
|
134
|
+
let!(:sibling) { DummyReferencedChildDocument.create(parent: parent) }
|
135
|
+
|
136
|
+
before(:each) do
|
137
|
+
subject.parent = parent
|
138
|
+
subject.save
|
139
|
+
end
|
140
|
+
|
141
|
+
it "returns the subject's siblings" do
|
142
|
+
subject.siblings(scope: :parent).to_a.should eq([sibling])
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context "when using multiple polymorphic relations" do
|
147
|
+
|
148
|
+
let!(:sibling) { DummyReferencedChildDocument.create.tap { |doc| parent.referenced_polymorphic_children1 << doc} }
|
149
|
+
|
150
|
+
before(:each) do
|
151
|
+
parent.referenced_polymorphic_children1 << subject
|
152
|
+
subject.save
|
153
|
+
end
|
154
|
+
|
155
|
+
it "returns the subject's siblings" do
|
156
|
+
subject.siblings(scope: :polymorphic_parent).to_a.should eq([sibling])
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context "when using an embedded relation" do
|
162
|
+
|
163
|
+
context "when using a non-polymorphic relation" do
|
164
|
+
|
165
|
+
subject { DummyEmbeddedChildDocument.create(parent: parent) }
|
166
|
+
let!(:sibling) { DummyEmbeddedChildDocument.create(parent: parent) }
|
167
|
+
|
168
|
+
it "returns the subject's siblings" do
|
169
|
+
subject.siblings(scope: :parent).to_a.should eq([sibling])
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context "when using a polymorphic relation" do
|
174
|
+
|
175
|
+
subject { DummyPolymorphicEmbeddedChildDocument.create(parent: parent) }
|
176
|
+
let!(:sibling) { DummyPolymorphicEmbeddedChildDocument.create(parent: parent) }
|
177
|
+
|
178
|
+
it "returns the subject's siblings" do
|
179
|
+
subject.siblings(scope: :parent).to_a.should eq([sibling])
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context "when using a simple attribute" do
|
185
|
+
|
186
|
+
subject { DummyReferencedChildDocument.create(parent: parent) }
|
187
|
+
let!(:sibling) { DummyReferencedChildDocument.create(parent: parent) }
|
188
|
+
|
189
|
+
it "returns the subject's siblings" do
|
190
|
+
subject.siblings(scope: :parent_id).to_a.should eq([sibling])
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
context "when not using a scope" do
|
197
|
+
|
198
|
+
context "when a default sibling scope is set" do
|
199
|
+
|
200
|
+
before(:each) do
|
201
|
+
DummyReferencedChildDocument.default_sibling_scope = :parent
|
202
|
+
end
|
203
|
+
|
204
|
+
after(:each) do
|
205
|
+
DummyReferencedChildDocument.default_sibling_scope = nil
|
206
|
+
end
|
207
|
+
|
208
|
+
subject { DummyReferencedChildDocument.create(parent: parent) }
|
209
|
+
let!(:sibling) { DummyReferencedChildDocument.create(parent: parent) }
|
210
|
+
|
211
|
+
it "returns the subject's siblings through the default sibling scope" do
|
212
|
+
subject.siblings.to_a.should eq([sibling])
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
context "when no default sibling scope is set" do
|
217
|
+
|
218
|
+
subject { DummyReferencedChildDocument.create }
|
219
|
+
let!(:sibling) { DummyReferencedChildDocument.create }
|
220
|
+
|
221
|
+
it "returns all other documents of the subject's type" do
|
222
|
+
subject.siblings.to_a.should eq([sibling])
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
describe "#siblings_and_self" do
|
229
|
+
|
230
|
+
subject { DummyReferencedChildDocument.create(parent: parent) }
|
231
|
+
let!(:sibling) { DummyReferencedChildDocument.create(parent: parent) }
|
232
|
+
|
233
|
+
it "returns the subject's siblings and the subject itself" do
|
234
|
+
subject.siblings_and_self(scope: :parent).to_a.sort.should eq([subject, sibling].sort)
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
describe "#sibling_of?" do
|
239
|
+
|
240
|
+
context "when using a fallback scope" do
|
241
|
+
|
242
|
+
let(:super_parent) { DummySuperParentDocument.create }
|
243
|
+
let(:parent) { DummyParentDocument.create }
|
244
|
+
subject { DummyReferencedChildDocument.create }
|
245
|
+
let!(:main_sibling) { DummyReferencedChildDocument.create(parent: parent, super_parent: super_parent) }
|
246
|
+
let!(:fallback_sibling) { DummyReferencedChildDocument.create(super_parent: super_parent) }
|
247
|
+
let!(:ultimate_sibling) { DummyReferencedChildDocument.create }
|
248
|
+
|
249
|
+
context "when providing scope values" do
|
250
|
+
|
251
|
+
let(:old_super_parent) { DummySuperParentDocument.create }
|
252
|
+
let(:old_parent) { DummyParentDocument.create }
|
253
|
+
|
254
|
+
before(:each) do
|
255
|
+
subject.parent = parent
|
256
|
+
subject.super_parent = super_parent
|
257
|
+
subject.save
|
258
|
+
end
|
259
|
+
|
260
|
+
context "when providing one scope value" do
|
261
|
+
|
262
|
+
let!(:old_main_sibling) { DummyReferencedChildDocument.create(parent: old_parent, super_parent: super_parent) }
|
263
|
+
|
264
|
+
context "when called with a sibling" do
|
265
|
+
|
266
|
+
it "returns true" do
|
267
|
+
subject.should be_sibling_of(
|
268
|
+
old_main_sibling,
|
269
|
+
scope: [:parent, :super_parent],
|
270
|
+
scope_values: {
|
271
|
+
parent: old_parent
|
272
|
+
}
|
273
|
+
)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
context "when not called with a sibling" do
|
278
|
+
|
279
|
+
it "returns false" do
|
280
|
+
subject.should_not be_sibling_of(
|
281
|
+
main_sibling,
|
282
|
+
scope: [:parent, :super_parent],
|
283
|
+
scope_values: {
|
284
|
+
parent: old_parent
|
285
|
+
}
|
286
|
+
)
|
287
|
+
subject.should_not be_sibling_of(
|
288
|
+
fallback_sibling,
|
289
|
+
scope: [:parent, :super_parent],
|
290
|
+
scope_values: {
|
291
|
+
parent: old_parent
|
292
|
+
}
|
293
|
+
)
|
294
|
+
subject.should_not be_sibling_of(
|
295
|
+
ultimate_sibling,
|
296
|
+
scope: [:parent, :super_parent],
|
297
|
+
scope_values: {
|
298
|
+
parent: old_parent
|
299
|
+
}
|
300
|
+
)
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
context "when providing multiple scope values" do
|
306
|
+
|
307
|
+
let!(:old_main_sibling) { DummyReferencedChildDocument.create(parent: old_parent, super_parent: old_super_parent) }
|
308
|
+
let!(:old_fallback_sibling) { DummyReferencedChildDocument.create(super_parent: old_super_parent) }
|
309
|
+
|
310
|
+
context "when the main sibling value was nil" do
|
311
|
+
|
312
|
+
context "when called with a sibling" do
|
313
|
+
|
314
|
+
it "returns true" do
|
315
|
+
subject.should be_sibling_of(
|
316
|
+
old_fallback_sibling,
|
317
|
+
scope: [:parent, :super_parent],
|
318
|
+
scope_values: {
|
319
|
+
parent: nil,
|
320
|
+
super_parent: old_super_parent
|
321
|
+
}
|
322
|
+
)
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
context "when not called with a sibling" do
|
327
|
+
|
328
|
+
it "returns false" do
|
329
|
+
subject.should_not be_sibling_of(
|
330
|
+
old_main_sibling,
|
331
|
+
scope: [:parent, :super_parent],
|
332
|
+
scope_values: {
|
333
|
+
parent: nil,
|
334
|
+
super_parent: old_super_parent
|
335
|
+
}
|
336
|
+
)
|
337
|
+
subject.should_not be_sibling_of(
|
338
|
+
main_sibling,
|
339
|
+
scope: [:parent, :super_parent],
|
340
|
+
scope_values: {
|
341
|
+
parent: nil,
|
342
|
+
super_parent: old_super_parent
|
343
|
+
}
|
344
|
+
)
|
345
|
+
subject.should_not be_sibling_of(
|
346
|
+
fallback_sibling,
|
347
|
+
scope: [:parent, :super_parent],
|
348
|
+
scope_values: {
|
349
|
+
parent: nil,
|
350
|
+
super_parent: old_super_parent
|
351
|
+
}
|
352
|
+
)
|
353
|
+
subject.should_not be_sibling_of(
|
354
|
+
ultimate_sibling,
|
355
|
+
scope: [:parent, :super_parent],
|
356
|
+
scope_values: {
|
357
|
+
parent: nil,
|
358
|
+
super_parent: old_super_parent
|
359
|
+
}
|
360
|
+
)
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
context "when the main sibling value was not nil" do
|
366
|
+
|
367
|
+
context "when called with a sibling" do
|
368
|
+
|
369
|
+
it "returns true" do
|
370
|
+
subject.should be_sibling_of(
|
371
|
+
old_main_sibling,
|
372
|
+
scope: [:parent, :super_parent],
|
373
|
+
scope_values: {
|
374
|
+
parent: old_parent,
|
375
|
+
super_parent: old_super_parent
|
376
|
+
}
|
377
|
+
)
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
context "when not called with a sibling" do
|
382
|
+
|
383
|
+
it "returns false" do
|
384
|
+
subject.should_not be_sibling_of(
|
385
|
+
old_fallback_sibling,
|
386
|
+
scope: [:parent, :super_parent],
|
387
|
+
scope_values: {
|
388
|
+
parent: old_parent,
|
389
|
+
super_parent: old_super_parent
|
390
|
+
}
|
391
|
+
)
|
392
|
+
subject.should_not be_sibling_of(
|
393
|
+
main_sibling,
|
394
|
+
scope: [:parent, :super_parent],
|
395
|
+
scope_values: {
|
396
|
+
parent: old_parent,
|
397
|
+
super_parent: old_super_parent
|
398
|
+
}
|
399
|
+
)
|
400
|
+
subject.should_not be_sibling_of(
|
401
|
+
fallback_sibling,
|
402
|
+
scope: [:parent, :super_parent],
|
403
|
+
scope_values: {
|
404
|
+
parent: old_parent,
|
405
|
+
super_parent: old_super_parent
|
406
|
+
}
|
407
|
+
)
|
408
|
+
subject.should_not be_sibling_of(
|
409
|
+
ultimate_sibling,
|
410
|
+
scope: [:parent, :super_parent],
|
411
|
+
scope_values: {
|
412
|
+
parent: old_parent,
|
413
|
+
super_parent: old_super_parent
|
414
|
+
}
|
415
|
+
)
|
416
|
+
end
|
417
|
+
end
|
418
|
+
end
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
context "when providing other scope values" do
|
423
|
+
|
424
|
+
let(:old_super_parent) { DummySuperParentDocument.create }
|
425
|
+
let(:old_parent) { DummyParentDocument.create }
|
426
|
+
|
427
|
+
before(:each) do
|
428
|
+
subject.parent = parent
|
429
|
+
subject.super_parent = super_parent
|
430
|
+
subject.save
|
431
|
+
end
|
432
|
+
|
433
|
+
context "when providing one other scope value" do
|
434
|
+
|
435
|
+
let!(:old_main_sibling) { DummyReferencedChildDocument.create(parent: old_parent, super_parent: super_parent) }
|
436
|
+
|
437
|
+
context "when called with a sibling" do
|
438
|
+
|
439
|
+
it "returns true" do
|
440
|
+
subject.should be_sibling_of(
|
441
|
+
old_main_sibling,
|
442
|
+
scope: [:parent, :super_parent],
|
443
|
+
other_scope_values: {
|
444
|
+
parent: parent
|
445
|
+
}
|
446
|
+
)
|
447
|
+
end
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
451
|
+
context "when providing multiple other scope values" do
|
452
|
+
|
453
|
+
let!(:old_main_sibling) { DummyReferencedChildDocument.create(parent: old_parent, super_parent: old_super_parent) }
|
454
|
+
let!(:old_fallback_sibling) { DummyReferencedChildDocument.create(super_parent: old_super_parent) }
|
455
|
+
|
456
|
+
context "when the other main sibling value was nil" do
|
457
|
+
|
458
|
+
before(:each) do
|
459
|
+
subject.parent = nil
|
460
|
+
subject.save
|
461
|
+
end
|
462
|
+
|
463
|
+
context "when called with a sibling" do
|
464
|
+
|
465
|
+
it "returns true" do
|
466
|
+
subject.should be_sibling_of(
|
467
|
+
old_fallback_sibling,
|
468
|
+
scope: [:parent, :super_parent],
|
469
|
+
other_scope_values: {
|
470
|
+
parent: nil,
|
471
|
+
super_parent: super_parent
|
472
|
+
}
|
473
|
+
)
|
474
|
+
end
|
475
|
+
end
|
476
|
+
end
|
477
|
+
|
478
|
+
context "when the other main sibling value was not nil" do
|
479
|
+
|
480
|
+
context "when called with a sibling" do
|
481
|
+
|
482
|
+
it "returns true" do
|
483
|
+
subject.should be_sibling_of(
|
484
|
+
old_main_sibling,
|
485
|
+
scope: [:parent, :super_parent],
|
486
|
+
other_scope_values: {
|
487
|
+
parent: parent,
|
488
|
+
super_parent: super_parent
|
489
|
+
}
|
490
|
+
)
|
491
|
+
end
|
492
|
+
end
|
493
|
+
end
|
494
|
+
end
|
495
|
+
end
|
496
|
+
|
497
|
+
context "when not providing scope values" do
|
498
|
+
|
499
|
+
context "when the document has a main scope document" do
|
500
|
+
|
501
|
+
before(:each) do
|
502
|
+
subject.parent = parent
|
503
|
+
subject.super_parent = super_parent
|
504
|
+
subject.save
|
505
|
+
end
|
506
|
+
|
507
|
+
context "when called with a sibling" do
|
508
|
+
|
509
|
+
it "returns true" do
|
510
|
+
subject.should be_sibling_of(main_sibling, scope: [:parent, :super_parent])
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
context "when not called with a sibling" do
|
515
|
+
|
516
|
+
it "returns false" do
|
517
|
+
subject.should_not be_sibling_of(fallback_sibling, scope: [:parent, :super_parent])
|
518
|
+
subject.should_not be_sibling_of(ultimate_sibling, scope: [:parent, :super_parent])
|
519
|
+
end
|
520
|
+
end
|
521
|
+
end
|
522
|
+
|
523
|
+
context "when the document has a fallback scope document but not a main scope document" do
|
524
|
+
|
525
|
+
before(:each) do
|
526
|
+
subject.super_parent = super_parent
|
527
|
+
subject.save
|
528
|
+
end
|
529
|
+
|
530
|
+
context "when called with a sibling" do
|
531
|
+
|
532
|
+
it "returns true" do
|
533
|
+
subject.should be_sibling_of(fallback_sibling, scope: [:parent, :super_parent])
|
534
|
+
end
|
535
|
+
end
|
536
|
+
|
537
|
+
context "when not called with a sibling" do
|
538
|
+
|
539
|
+
it "returns false" do
|
540
|
+
subject.should_not be_sibling_of(main_sibling, scope: [:parent, :super_parent])
|
541
|
+
subject.should_not be_sibling_of(ultimate_sibling, scope: [:parent, :super_parent])
|
542
|
+
end
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
context "when the document has neither a main scope document or a fallback scope document" do
|
547
|
+
|
548
|
+
context "when called with a sibling" do
|
549
|
+
|
550
|
+
it "returns true" do
|
551
|
+
subject.should be_sibling_of(ultimate_sibling, scope: [:parent, :super_parent])
|
552
|
+
end
|
553
|
+
end
|
554
|
+
|
555
|
+
context "when not called with a sibling" do
|
556
|
+
|
557
|
+
it "returns false" do
|
558
|
+
subject.should_not be_sibling_of(main_sibling, scope: [:parent, :super_parent])
|
559
|
+
subject.should_not be_sibling_of(fallback_sibling, scope: [:parent, :super_parent])
|
560
|
+
end
|
561
|
+
end
|
562
|
+
end
|
563
|
+
end
|
564
|
+
end
|
565
|
+
|
566
|
+
context "when using a scope" do
|
567
|
+
|
568
|
+
context "when called with a sibling" do
|
569
|
+
|
570
|
+
subject { DummyReferencedChildDocument.create(parent: parent) }
|
571
|
+
let(:sibling) { DummyReferencedChildDocument.create(parent: parent) }
|
572
|
+
|
573
|
+
it "returns true" do
|
574
|
+
subject.should be_sibling_of(sibling, scope: :parent)
|
575
|
+
end
|
576
|
+
end
|
577
|
+
|
578
|
+
context "when not called with a sibling" do
|
579
|
+
|
580
|
+
subject { DummyReferencedChildDocument.create(parent: parent) }
|
581
|
+
let(:other_parent) { DummyParentDocument.create }
|
582
|
+
let(:non_sibling) { DummyReferencedChildDocument.create(parent: other_parent) }
|
583
|
+
|
584
|
+
it "returns false" do
|
585
|
+
subject.should_not be_sibling_of(non_sibling, scope: :parent)
|
586
|
+
end
|
587
|
+
end
|
588
|
+
end
|
589
|
+
|
590
|
+
context "when not using a scope" do
|
591
|
+
|
592
|
+
context "when called with a sibling" do
|
593
|
+
|
594
|
+
subject { DummyReferencedChildDocument.create }
|
595
|
+
let(:sibling) { DummyReferencedChildDocument.create }
|
596
|
+
|
597
|
+
it "returns true" do
|
598
|
+
subject.should be_sibling_of(sibling)
|
599
|
+
end
|
600
|
+
end
|
601
|
+
|
602
|
+
context "when not called with a sibling" do
|
603
|
+
|
604
|
+
subject { DummyReferencedChildDocument.create }
|
605
|
+
|
606
|
+
it "returns false" do
|
607
|
+
subject.should_not be_sibling_of(parent)
|
608
|
+
end
|
609
|
+
end
|
610
|
+
end
|
611
|
+
end
|
612
|
+
|
613
|
+
describe "#sibling_of!" do
|
614
|
+
|
615
|
+
context "when called with a sibling" do
|
616
|
+
|
617
|
+
let(:parent) { DummyParentDocument.create }
|
618
|
+
subject { DummyReferencedChildDocument.create(parent: parent) }
|
619
|
+
let!(:sibling) { DummyReferencedChildDocument.create(parent: parent) }
|
620
|
+
|
621
|
+
it "returns true" do
|
622
|
+
subject.sibling_of!(sibling, scope: :parent).should be_true
|
623
|
+
end
|
624
|
+
|
625
|
+
it "doesn't save the subject" do
|
626
|
+
subject.should_not_receive(:save!)
|
627
|
+
|
628
|
+
subject.sibling_of!(sibling, scope: :parent)
|
629
|
+
end
|
630
|
+
end
|
631
|
+
|
632
|
+
context "when not called with a sibling" do
|
633
|
+
|
634
|
+
context "when called with an object that can never be a sibling" do
|
635
|
+
|
636
|
+
let(:parent) { DummyParentDocument.create }
|
637
|
+
subject { DummyReferencedChildDocument.create(parent: parent) }
|
638
|
+
let!(:non_sibling) { DummyParentDocument.create }
|
639
|
+
|
640
|
+
it "returns false" do
|
641
|
+
subject.sibling_of!(non_sibling, scope: :parent).should be_false
|
642
|
+
end
|
643
|
+
end
|
644
|
+
|
645
|
+
context "when called with an object that could be a sibling" do
|
646
|
+
|
647
|
+
let(:super_parent) { DummySuperParentDocument.create }
|
648
|
+
let(:parent) { DummyParentDocument.create }
|
649
|
+
subject { DummyReferencedChildDocument.create }
|
650
|
+
let!(:new_sibling) { DummyReferencedChildDocument.create(parent_id: parent.id, super_parent: super_parent) }
|
651
|
+
|
652
|
+
let(:options) { [new_sibling, scope: [:parent_id, :super_parent]] }
|
653
|
+
|
654
|
+
it "copies the scope values from the object to the subject" do
|
655
|
+
subject.sibling_of!(*options)
|
656
|
+
|
657
|
+
subject.parent_id.should eq(new_sibling.parent_id)
|
658
|
+
subject.super_parent.should eq(new_sibling.super_parent)
|
659
|
+
end
|
660
|
+
|
661
|
+
it "saves the subject" do
|
662
|
+
subject.should_receive(:save!)
|
663
|
+
|
664
|
+
subject.sibling_of!(*options)
|
665
|
+
end
|
666
|
+
|
667
|
+
it "returns true" do
|
668
|
+
subject.sibling_of!(*options).should be_true
|
669
|
+
end
|
670
|
+
|
671
|
+
it "makes the subject a sibling of the object" do
|
672
|
+
subject.sibling_of!(*options).should be_true
|
673
|
+
|
674
|
+
subject.should be_sibling_of(*options)
|
675
|
+
end
|
676
|
+
end
|
677
|
+
end
|
678
|
+
end
|
679
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
3
|
+
|
4
|
+
require "mongoid"
|
5
|
+
require "mongoid/siblings"
|
6
|
+
|
7
|
+
require "rspec"
|
8
|
+
|
9
|
+
Mongoid.configure do |config|
|
10
|
+
config.connect_to "mongoid_siblings_test"
|
11
|
+
end
|
12
|
+
|
13
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
config.after :each do
|
17
|
+
Mongoid::Config.purge!
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class DummySuperParentDocument
|
2
|
+
include Mongoid::Document
|
3
|
+
|
4
|
+
has_many :children, class_name: "DummyReferencedChildDocument",
|
5
|
+
inverse_of: :super_parent
|
6
|
+
end
|
7
|
+
|
8
|
+
class DummyParentDocument
|
9
|
+
include Mongoid::Document
|
10
|
+
|
11
|
+
has_many :referenced_children, class_name: "DummyReferencedChildDocument",
|
12
|
+
inverse_of: :parent
|
13
|
+
has_many :referenced_polymorphic_children1, class_name: "DummyReferencedChildDocument",
|
14
|
+
as: :polymorphic_parent
|
15
|
+
has_many :referenced_polymorphic_children2, class_name: "DummyReferencedChildDocument",
|
16
|
+
as: :polymorphic_parent
|
17
|
+
|
18
|
+
embeds_many :embedded_children, class_name: "DummyEmbeddedChildDocument",
|
19
|
+
inverse_of: :parent
|
20
|
+
embeds_many :embedded_polymorphic_children, class_name: "DummyPolymorphicEmbeddedChildDocument",
|
21
|
+
as: :parent
|
22
|
+
end
|
23
|
+
|
24
|
+
class DummyReferencedChildDocument
|
25
|
+
include Mongoid::Document
|
26
|
+
include Mongoid::Siblings
|
27
|
+
|
28
|
+
belongs_to :super_parent, class_name: DummySuperParentDocument.to_s,
|
29
|
+
inverse_of: :children
|
30
|
+
|
31
|
+
belongs_to :parent, class_name: DummyParentDocument.to_s,
|
32
|
+
inverse_of: :referenced_children
|
33
|
+
belongs_to :polymorphic_parent, polymorphic: true
|
34
|
+
end
|
35
|
+
|
36
|
+
class DummyEmbeddedChildDocument
|
37
|
+
include Mongoid::Document
|
38
|
+
include Mongoid::Siblings
|
39
|
+
|
40
|
+
embedded_in :parent, class_name: DummyParentDocument.to_s,
|
41
|
+
inverse_of: :embedded_children
|
42
|
+
end
|
43
|
+
|
44
|
+
class DummyPolymorphicEmbeddedChildDocument
|
45
|
+
include Mongoid::Document
|
46
|
+
include Mongoid::Siblings
|
47
|
+
|
48
|
+
embedded_in :parent, polymorphic: true
|
49
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mongoid-siblings
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Douwe Maan
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-09 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: mongoid
|
16
|
+
requirement: &70235283618700 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '3.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70235283618700
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &70235283618220 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70235283618220
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &70235283617640 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70235283617640
|
47
|
+
description: mongoid-siblings adds methods to enable you to easily access your Mongoid
|
48
|
+
document's siblings.
|
49
|
+
email: douwe@selenight.nl
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- lib/mongoid/siblings.rb
|
55
|
+
- LICENSE
|
56
|
+
- README.md
|
57
|
+
- Rakefile
|
58
|
+
- Gemfile
|
59
|
+
- spec/mongoid/siblings_spec.rb
|
60
|
+
- spec/spec_helper.rb
|
61
|
+
- spec/support/models.rb
|
62
|
+
homepage: https://github.com/DouweM/mongoid-siblings
|
63
|
+
licenses:
|
64
|
+
- MIT
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ! '>='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
segments:
|
76
|
+
- 0
|
77
|
+
hash: -1413753754356574329
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ! '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
segments:
|
85
|
+
- 0
|
86
|
+
hash: -1413753754356574329
|
87
|
+
requirements: []
|
88
|
+
rubyforge_project:
|
89
|
+
rubygems_version: 1.8.6
|
90
|
+
signing_key:
|
91
|
+
specification_version: 3
|
92
|
+
summary: Easy access to your Mongoid document's siblings.
|
93
|
+
test_files:
|
94
|
+
- spec/mongoid/siblings_spec.rb
|
95
|
+
- spec/spec_helper.rb
|
96
|
+
- spec/support/models.rb
|