get 0.3.0 → 0.3.1
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.
- checksums.yaml +4 -4
- data/README.md +61 -0
- data/lib/get/builders/join_builder.rb +38 -0
- data/lib/get/builders.rb +2 -0
- data/lib/get/parser.rb +1 -1
- data/lib/get.rb +1 -0
- data/spec/get_spec.rb +70 -0
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e87e789020578ba92ef03c7e3a98f9634f85f762
|
4
|
+
data.tar.gz: e8181e6da0904a709a7f532d8157310f4d16fc16
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a68bd91a8407162804dc0d6cdeaa702cee0782f798cbc58ca1a2e086a37c3f38e83e5237a5812a3729a5d20610a15b396e4a568b9e4900e56c198fa162419b0
|
7
|
+
data.tar.gz: 08371505e8ac657c5c88fb7f02ffdf986e5a1d824b6ca239c3ab52257a0d8443dff9ee534482fa27a6fcf271aa54032d3b2982a99a12000787a2d2e4b237ead7
|
data/README.md
CHANGED
@@ -67,6 +67,59 @@ Get::SportscarsFromUser.run(user, via: :employer, conditions: { make: 'Audi' },
|
|
67
67
|
Keep the plurality of associations in mind. If an Employer has many Users, UsersFromEmployer works,
|
68
68
|
but UserFromEmployer will throw `Get::Errors::InvalidAncestry`.
|
69
69
|
|
70
|
+
## Joins
|
71
|
+
|
72
|
+
Associations use 'JoinedWith', and make the dark world of joins much more palatable.
|
73
|
+
Joins will always return a Horza::Collection.
|
74
|
+
|
75
|
+
*It is recommended to pass a fields hash when using Get joins.
|
76
|
+
If you do not, your database implementation will decide which values are placed in fields with common names, like :id.*
|
77
|
+
|
78
|
+
Join on related ids, select multiple fields
|
79
|
+
```ruby
|
80
|
+
join_params = {
|
81
|
+
on: { employer_id: :id }, # base_table(users).employer_id = join_table(employers).id
|
82
|
+
fields: {
|
83
|
+
users: [:first_name, :last_name],
|
84
|
+
employers: [:address],
|
85
|
+
}
|
86
|
+
}
|
87
|
+
UsersJoinedWithEmployers.run(join_params)
|
88
|
+
```
|
89
|
+
|
90
|
+
Join on related ids, select multiple fields - with conditions, limit, and offset
|
91
|
+
```ruby
|
92
|
+
join_params = {
|
93
|
+
on: { employer_id: :id }, # base_table(users).employer_id = join_table(employers).id
|
94
|
+
fields: {
|
95
|
+
users: [:first_name, :last_name],
|
96
|
+
employers: [:address],
|
97
|
+
},
|
98
|
+
conditions: {
|
99
|
+
users: { last_name: 'Turner' },
|
100
|
+
employers: { company_name: 'Corporation ltd.' }
|
101
|
+
},
|
102
|
+
limit: 10,
|
103
|
+
offset: 5
|
104
|
+
}
|
105
|
+
UsersJoinedWithEmployers.run(join_params)
|
106
|
+
```
|
107
|
+
|
108
|
+
Join on multiple requirements, alias field names
|
109
|
+
```ruby
|
110
|
+
join_params = {
|
111
|
+
on: [
|
112
|
+
{ employer_id: :id }, # base_table(users).employer_id = join_table(employers).id
|
113
|
+
{ email: :email }, # base_table(users).email = join_table(employers).email
|
114
|
+
]
|
115
|
+
fields: {
|
116
|
+
users: [:id, { first_name: :my_alias_for_first_name }],
|
117
|
+
employers: [:email, { id: :my_alias_for_employer_id }]
|
118
|
+
}
|
119
|
+
}
|
120
|
+
UsersJoinedWithEmployers.run(join_params)
|
121
|
+
```
|
122
|
+
|
70
123
|
## Options
|
71
124
|
|
72
125
|
**Base Options**
|
@@ -88,6 +141,14 @@ Key | Type | Details
|
|
88
141
|
`eager_load` | Boolean | Whether to eager_load the association
|
89
142
|
`via` | [Symbol] | The associations that need to be traversed in order to reach the desired record(s). These must be in the correct order, ie user.employer.parent.children would be Get::ChildrenFromUser.run(user_id, via: [:employer, :parent]). You can also pass a single symbol instead of an array of length 1.
|
90
143
|
|
144
|
+
**Join Options**
|
145
|
+
|
146
|
+
Key | Type | Details
|
147
|
+
--- | ---- | -------
|
148
|
+
`on` | Hash or Array of Hashes | Key value pairs representing base_table field => join_table field
|
149
|
+
`fields` | Hash | Keys are the table names, values are array of field names or hashes defining the field's alias for the join. See examples above.
|
150
|
+
`conditions` | Hash | Keys are the table names, values are Key value pairs for the query. See examples above.
|
151
|
+
|
91
152
|
## Why is this necessary?
|
92
153
|
|
93
154
|
#### Problem 1: Encapsulation
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Get
|
2
|
+
module Builders
|
3
|
+
class JoinBuilder < BaseBuilder
|
4
|
+
private
|
5
|
+
|
6
|
+
def class_args
|
7
|
+
{
|
8
|
+
base_table: @result_entity.symbolize,
|
9
|
+
join_table: @key,
|
10
|
+
store: Get.adapter.context_for_entity(@result_entity.singularize.symbolize)
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
def template_class(args)
|
15
|
+
Class.new(::Get::Db) do
|
16
|
+
include Get
|
17
|
+
|
18
|
+
class << self
|
19
|
+
attr_reader :base_table, :join_table
|
20
|
+
end
|
21
|
+
|
22
|
+
@base_table, @join_table, @store = args[:base_table], args[:join_table], args[:store]
|
23
|
+
|
24
|
+
def initialize(options)
|
25
|
+
@options = options.merge(with: self.class.join_table)
|
26
|
+
super(query_params)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def query_params
|
32
|
+
{ join: @options }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/get/builders.rb
CHANGED
data/lib/get/parser.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Get
|
2
2
|
class Parser
|
3
|
-
CLASS_REGEX = /^(.*)(By|From)(.*)/
|
3
|
+
CLASS_REGEX = /^(.*)(By|From|JoinedWith)(.*)/
|
4
4
|
CLASS_NAME_BY_ERROR = 'You have multiple instances of "By" in your class. Please use open-ended form ie. Get::UserBy.run(params)'
|
5
5
|
attr_accessor :class_name, :result_entity, :method
|
6
6
|
|
data/lib/get.rb
CHANGED
data/spec/get_spec.rb
CHANGED
@@ -379,6 +379,69 @@ describe Get do
|
|
379
379
|
end
|
380
380
|
end
|
381
381
|
end
|
382
|
+
|
383
|
+
context 'joins' do
|
384
|
+
let(:employer) { GetSpec::Employer.create }
|
385
|
+
let(:employer2) { GetSpec::Employer.create }
|
386
|
+
let(:match_count) { 20 }
|
387
|
+
let(:miss_count) { 7 }
|
388
|
+
|
389
|
+
before do
|
390
|
+
match_count.times { employer2.users << GetSpec::User.create(employer: employer2) }
|
391
|
+
miss_count.times { employer.users << GetSpec::User.create(employer: employer) }
|
392
|
+
end
|
393
|
+
|
394
|
+
context 'when no conditions are passed' do
|
395
|
+
let(:join_params) do
|
396
|
+
{
|
397
|
+
on: { employer_id: :id } # field for adapted model => field for join model
|
398
|
+
}
|
399
|
+
end
|
400
|
+
|
401
|
+
it 'returns match_count + miss_count joines records' do
|
402
|
+
result = Get::UsersJoinedWithEmployers.run(join_params)
|
403
|
+
expect(result.length).to eq match_count + miss_count
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
context 'when conditions are passed' do
|
408
|
+
let(:join_params) do
|
409
|
+
{
|
410
|
+
on: { employer_id: :id }, # field for adapted model => field for join model
|
411
|
+
conditions: {
|
412
|
+
employers: { id: employer2.id }
|
413
|
+
}
|
414
|
+
}
|
415
|
+
end
|
416
|
+
|
417
|
+
it 'returns match_count joined records' do
|
418
|
+
result = Get::UsersJoinedWithEmployers.run(join_params)
|
419
|
+
expect(result.length).to eq match_count
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
context 'when conditions and fields are passed' do
|
424
|
+
let(:join_params) do
|
425
|
+
{
|
426
|
+
on: { employer_id: :id }, # field for adapted model => field for join model
|
427
|
+
conditions: {
|
428
|
+
employers: { id: employer2.id }
|
429
|
+
},
|
430
|
+
fields: {
|
431
|
+
users: [:id],
|
432
|
+
employers: [{id: :my_employer_id}]
|
433
|
+
}
|
434
|
+
}
|
435
|
+
end
|
436
|
+
|
437
|
+
it 'returns match_count joined records' do
|
438
|
+
result = Get::UsersJoinedWithEmployers.run(join_params)
|
439
|
+
expect(result.length).to eq match_count
|
440
|
+
expect(result.first.my_employer_id).to eq employer2.id
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
444
|
+
end
|
382
445
|
end
|
383
446
|
end
|
384
447
|
|
@@ -427,6 +490,7 @@ end
|
|
427
490
|
describe Get::Parser do
|
428
491
|
let(:ancestry_name) { 'UserFromEmployer' }
|
429
492
|
let(:query_name) { 'UserFromEmployer' }
|
493
|
+
let(:join_name) { 'UsersJoinedWithEmployers' }
|
430
494
|
|
431
495
|
subject { Get::Parser }
|
432
496
|
before { Get.configure { |config| config.adapter = :active_record } }
|
@@ -445,6 +509,12 @@ describe Get::Parser do
|
|
445
509
|
end
|
446
510
|
end
|
447
511
|
|
512
|
+
context 'when name is of join type' do
|
513
|
+
it 'returns true' do
|
514
|
+
expect(subject.new(join_name).match?).to be true
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
448
518
|
context 'when name is of no type' do
|
449
519
|
it 'returns false' do
|
450
520
|
expect(subject.new('Blablabla').match?).to be false
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: get
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Blake Turner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: horza
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.4.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.4.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -120,6 +120,7 @@ files:
|
|
120
120
|
- lib/get/builders.rb
|
121
121
|
- lib/get/builders/ancestry_builder.rb
|
122
122
|
- lib/get/builders/base_builder.rb
|
123
|
+
- lib/get/builders/join_builder.rb
|
123
124
|
- lib/get/builders/query_builder.rb
|
124
125
|
- lib/get/configuration.rb
|
125
126
|
- lib/get/db.rb
|