mongoid_embed_finder 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +12 -1
- data/lib/mongoid_embed_finder/projectors/base.rb +11 -2
- data/lib/mongoid_embed_finder/runner.rb +5 -4
- data/lib/mongoid_embed_finder/version.rb +1 -1
- data/spec/mongoid_embed_finder/projectors/single_spec.rb +29 -10
- data/spec/mongoid_embed_finder/runner_spec.rb +44 -4
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a4b0eab4a0e78f65604f3782019c1f8a96c2366d
|
4
|
+
data.tar.gz: bda098c893739bf97833edd34afff02f1f98f804
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a30f6b29f97ee61c425509401d150be9a66925b985c8bc1a4eb8a2646b50810c1ffa3695fe0b0736d5cb3d15c16f0a81c4af9c8adfdd050d7e905873cb52a42a
|
7
|
+
data.tar.gz: 4ad9f506675098f170a4eb290075518635c40be55af464c98c702168ee5b512bae392d91a5eba639285e7bb29e30664524424ae84989c0d644528606a27c7d30
|
data/README.md
CHANGED
@@ -28,10 +28,11 @@ Let's say that you have defined two classes as follows:
|
|
28
28
|
include Mongoid::Document
|
29
29
|
embedded_in :car
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
class Car
|
33
33
|
include Mongoid::Document
|
34
34
|
embeds_many :doors
|
35
|
+
field :name, type: String
|
35
36
|
end
|
36
37
|
|
37
38
|
Now you can easily retrieve instances of `Door` class using `finder`:
|
@@ -53,6 +54,16 @@ If you have `door_id` and `car_id` as well, you can narrow scope of cars:
|
|
53
54
|
In general you can basically pass any set of child's and parent's attributes.
|
54
55
|
Latter group should be passed under `parent` key. Those attributes are passed down to `Mongoid::Criteria`.
|
55
56
|
|
57
|
+
### Warning!
|
58
|
+
|
59
|
+
If your embedded object has other referenced entities they will not be loaded.
|
60
|
+
|
61
|
+
By default no parent's attributes are set except its primary key. It is deliberate to limit
|
62
|
+
amount of returned data.
|
63
|
+
To retrieve parent's attributes list them under `parent.include_fields` as follows:
|
64
|
+
|
65
|
+
finder.first(id: door_id, parent: { id: car_id, include_fields: [:name] })
|
66
|
+
|
56
67
|
## Contributing
|
57
68
|
|
58
69
|
1. Fork it ( https://github.com/growthrepublic/mongoid_embed_finder/fork )
|
@@ -5,14 +5,23 @@ module MongoidEmbedFinder
|
|
5
5
|
{ relation.key => { operator => query.child_criteria.selector }}
|
6
6
|
end
|
7
7
|
|
8
|
-
def project
|
8
|
+
def project(fields = [])
|
9
|
+
projection_with_fields = projection.merge(include_fields(fields))
|
9
10
|
query.scope_parent(projection)
|
10
|
-
query.execute.select(
|
11
|
+
query.execute.select(projection_with_fields)
|
11
12
|
end
|
12
13
|
|
13
14
|
def operator
|
14
15
|
raise NotImplementedError, "operator needs to be overriden"
|
15
16
|
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def include_fields(fields)
|
21
|
+
fields.inject({}) do
|
22
|
+
|acc, name| acc.merge(name => 1)
|
23
|
+
end
|
24
|
+
end
|
16
25
|
end
|
17
26
|
end
|
18
27
|
end
|
@@ -20,7 +20,8 @@ module MongoidEmbedFinder
|
|
20
20
|
|
21
21
|
def find_first(attrs = {}, parent: {})
|
22
22
|
query = build_nested_query(attrs, parent: parent)
|
23
|
-
project_query(query, Projectors::Single
|
23
|
+
project_query(query, Projectors::Single,
|
24
|
+
parent_fields: parent.fetch(:include_fields, [])).first
|
24
25
|
end
|
25
26
|
|
26
27
|
def build_nested_query(attrs = {}, parent: {})
|
@@ -28,13 +29,13 @@ module MongoidEmbedFinder
|
|
28
29
|
child_criteria = relations.child_class.criteria
|
29
30
|
|
30
31
|
NestedQuery.new(parent_criteria, child_criteria).tap do |query|
|
31
|
-
query.scope_parent(parent)
|
32
|
+
query.scope_parent(parent.except(:include_fields))
|
32
33
|
query.scope_child(attrs)
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
36
|
-
def project_query(query, projector_class)
|
37
|
-
projector_class.new(query, relations.children).project
|
37
|
+
def project_query(query, projector_class, parent_fields: [])
|
38
|
+
projector_class.new(query, relations.children).project(parent_fields)
|
38
39
|
end
|
39
40
|
|
40
41
|
def build_child_with_parent(nested_attrs)
|
@@ -19,19 +19,38 @@ describe MongoidEmbedFinder::Projectors::Single do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
describe "#project" do
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
context "without fields to include" do
|
23
|
+
it "extend parent's criteria" do
|
24
|
+
subject.project
|
25
|
+
expect(query).to have_received(:scope_parent).with(subject.projection)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "projects query" do
|
29
|
+
subject.project
|
30
|
+
expect(query).to have_received(:execute)
|
31
|
+
expect(query.execute).to have_received(:select).with(subject.projection)
|
32
|
+
end
|
26
33
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
expect(query.execute).to have_received(:select).with(subject.projection)
|
34
|
+
it "returns projection result" do
|
35
|
+
expect(subject.project).to eq projection_result
|
36
|
+
end
|
31
37
|
end
|
32
38
|
|
33
|
-
|
34
|
-
|
39
|
+
context "with fields to include" do
|
40
|
+
it "extend parent's criteria" do
|
41
|
+
subject.project
|
42
|
+
expect(query).to have_received(:scope_parent).with(subject.projection)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "projects query with parent's fields" do
|
46
|
+
subject.project([:name])
|
47
|
+
expect(query).to have_received(:execute)
|
48
|
+
expect(query.execute).to have_received(:select).with(subject.projection.merge(name: 1))
|
49
|
+
end
|
50
|
+
|
51
|
+
it "returns projection result" do
|
52
|
+
expect(subject.project).to eq projection_result
|
53
|
+
end
|
35
54
|
end
|
36
55
|
end
|
37
56
|
end
|
@@ -17,18 +17,58 @@ describe MongoidEmbedFinder::Runner do
|
|
17
17
|
|
18
18
|
context "by child_id and parent_id" do
|
19
19
|
it "returns the child" do
|
20
|
-
|
20
|
+
result = subject.first(
|
21
21
|
id: cars[1].doors[1].id.to_s,
|
22
22
|
parent: { id: cars[1].id.to_s })
|
23
23
|
|
24
|
-
expect(
|
24
|
+
expect(result).to eq cars[1].doors[1]
|
25
|
+
end
|
26
|
+
|
27
|
+
context "not listed parent's attributes" do
|
28
|
+
it "sets only id" do
|
29
|
+
result = subject.first(
|
30
|
+
id: cars[1].doors[1].id.to_s,
|
31
|
+
parent: { id: cars[1].id.to_s })
|
32
|
+
|
33
|
+
expect(result.car.id).to eq cars[1].id
|
34
|
+
expect(result.car.name).to be_nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "listed parent's attributes" do
|
39
|
+
it "sets listed attributes" do
|
40
|
+
result = subject.first(
|
41
|
+
id: cars[1].doors[1].id.to_s,
|
42
|
+
parent: { id: cars[1].id.to_s, include_fields: [:name] })
|
43
|
+
|
44
|
+
expect(result.car.id).to eq cars[1].id
|
45
|
+
expect(result.car.name).to eq cars[1].name
|
46
|
+
end
|
25
47
|
end
|
26
48
|
end
|
27
49
|
|
28
50
|
context "no parent attributes" do
|
29
51
|
it "returns the child" do
|
30
|
-
|
31
|
-
expect(
|
52
|
+
result = subject.first(id: cars[1].doors[1].id.to_s)
|
53
|
+
expect(result).to eq cars[1].doors[1]
|
54
|
+
end
|
55
|
+
|
56
|
+
context "not listed parent's attributes" do
|
57
|
+
it "sets only id" do
|
58
|
+
result = subject.first(id: cars[1].doors[1].id.to_s)
|
59
|
+
expect(result.car.id).to eq cars[1].id
|
60
|
+
expect(result.car.name).to be_nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "listed parent's attributes" do
|
65
|
+
it "sets listed attributes" do
|
66
|
+
result = subject.first(id: cars[1].doors[1].id.to_s,
|
67
|
+
parent: { include_fields: [:name] })
|
68
|
+
|
69
|
+
expect(result.car.id).to eq cars[1].id
|
70
|
+
expect(result.car.name).to eq cars[1].name
|
71
|
+
end
|
32
72
|
end
|
33
73
|
end
|
34
74
|
|