horza 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 75fcb74059583a6a1d2db95b90c205df028f4ca4
4
- data.tar.gz: f3580ea7b8820ddf78398e0eb241b73f6c66f160
3
+ metadata.gz: 2e84ae0d471c92bf87ccaa0894984e2eb1b874b3
4
+ data.tar.gz: 82a91f1e8c57dfcef55e900824509357d28bd955
5
5
  SHA512:
6
- metadata.gz: 2d8c3d3399690a7214c944a67a6960826d429367326266bac3561f0a5095db8a9285aab13cf348bf9665e80c201ae2c5a459cc6b7c9ab2b6e0a71fea82b6cb6e
7
- data.tar.gz: e206eb74ba5391dfd7ee5ffad4994cdf7e44e12bbb19fb901f132c7792d2543052244b00eb7100f3219749a411efdf880c4390b16f15ea5640e27796752e0139
6
+ metadata.gz: 4a9b216d669260c8bb880c5ee0bb97501a736709841cbffc05b34028f0e0b5f250b5eab7ef7205abdeb0c57d1df1c66b328313a6d899fd86e32f52b35a6660cb
7
+ data.tar.gz: 06458d7480062e516133d9e0f557ec299c1cda2a936d040cf1f096a51cfe694a934138bd3f2912dd0fbad2aeae5b4242b22ec6a1f2233890aab4981246e929ba
data/README.md CHANGED
@@ -16,22 +16,59 @@ end
16
16
  **Get Adapter for your ORM Object**
17
17
  ```ruby
18
18
  # ActiveRecord Example
19
- # Don't worry, We don't actually call things horza_users in our codebase, this is just for emphasis
20
- horza_user = Horza.adapt(User)
19
+ user = Horza.adapt(User)
21
20
 
22
21
  # Examples
23
- horza_user.get(id) # Find by id - Return nil on fail
24
- horza_user.get!(id) # Find by id - Error on fail
25
- horza_user.find_first(params) # Find 1 user - Orders by id desc by default - Return nil on fail
26
- horza_user.find_first!(params) # Find 1 user - Orders by id desc by default - Error nil on fail
27
- horza_user.find_all(params) # Find all users that match parameters
28
- horza_user.create(params) # Create record - return nil on fail
29
- horza_user.create!(params) # Create record - raise error on fail
30
- horza_user.update(params) # Update record - return nil on fail
31
- horza_user.update!(params) # Update record - raise error on fail
32
- horza_user.delete(params) # Delete record - return nil on fail
33
- horza_user.delete!(params) # Delete record - raise error on fail
34
- horza_user.ancestors(target: :employer, via: []) # Traverse relations
22
+ user.get(id) # Find by id - Return nil on fail
23
+ user.get!(id) # Find by id - Error on fail
24
+ user.find_first(options) # Find 1 user - Orders by id desc by default - Return nil on fail
25
+ user.find_first!(options) # Find 1 user - Orders by id desc by default - Error nil on fail
26
+ user.find_all(options) # Find all users that match parameters
27
+ user.create(options) # Create record - return nil on fail
28
+ user.create!(options) # Create record - raise error on fail
29
+ user.update(options) # Update record - return nil on fail
30
+ user.update!(options) # Update record - raise error on fail
31
+ user.delete(options) # Delete record - return nil on fail
32
+ user.delete!(options) # Delete record - raise error on fail
33
+ user.association(target: :employer, via: []) # Traverse association
34
+ ```
35
+
36
+ ## Options
37
+
38
+ **Base Options**
39
+
40
+ Key | Type | Details
41
+ ___ | ____ | _______
42
+ `conditions` | Hash | Key value pairs for the query
43
+ `order` | Hash | { `field` => `:asc`/`:desc` }
44
+ `limit` | Integer | Number of records to return
45
+ `offset` | Integer | Number of records to offset
46
+ `id` | Integer | The id of the root object (associations only)
47
+ `target` | Symbol | The target of the association - ie. employer.users would have a target of :users (associations only)
48
+ `eager_load` | Boolean | Whether to eager_load the association (associations only)
49
+
50
+ **Association Options**
51
+
52
+ Key | Type | Details
53
+ ___ | ____ | _______
54
+ `id` | Integer | The id of the root object
55
+ `target` | Symbol | The target of the association - ie. employer.users would have a target of :users
56
+ `eager_load` | Boolean | Whether to eager_load the association
57
+
58
+ ```ruby
59
+ conditions = { last_name: 'Turner' }
60
+
61
+ # Ordering
62
+ user.find_all(conditions: conditions, order: { last_name: :desc })
63
+
64
+ # Limiting
65
+ user.find_all(conditions: conditions, limit: 20)
66
+
67
+ # Offset
68
+ user.find_all(conditions: conditions, offset: 50)
69
+
70
+ # Eager loading associations
71
+ user.association(target: :sports_cars, via: [:employer], conditions: { make: 'Audi' }, eager_load: true)
35
72
  ```
36
73
 
37
74
  ## Outputs
@@ -42,7 +79,7 @@ Collection entities behave like arrays.
42
79
 
43
80
  ```ruby
44
81
  # Singular Entity
45
- result = horza_user.find_first(first_name: 'Blake')
82
+ result = user.find_first(first_name: 'Blake')
46
83
 
47
84
  result # => {"id"=>1, "first_name"=>"Blake", "last_name"=>"Turner", "employer_id"=>1}
48
85
  result.class.name # => "Horza::Entities::Single"
@@ -51,7 +88,7 @@ result.id # => 1
51
88
  result.id? # => true
52
89
 
53
90
  # Collection Entity
54
- result = horza_user.find_all(last_name: 'Turner')
91
+ result = user.find_all(last_name: 'Turner')
55
92
 
56
93
  result.class.name # => "Horza::Entities::Collection"
57
94
  result.length # => 1
@@ -3,6 +3,7 @@ module Horza
3
3
  class AbstractAdapter
4
4
  extend ::Horza::Adapters::ClassMethods
5
5
  include ::Horza::Adapters::InstanceMethods
6
+ extend ActiveSupport::DescendantsTracker
6
7
 
7
8
  attr_reader :context
8
9
 
@@ -40,7 +41,7 @@ module Horza
40
41
  not_implemented_error
41
42
  end
42
43
 
43
- def ancestors(options = {})
44
+ def association(options = {})
44
45
  not_implemented_error
45
46
  end
46
47
 
@@ -23,11 +23,11 @@ module Horza
23
23
  end
24
24
 
25
25
  def find_first!(options = {})
26
- run_and_convert_exceptions { entity_class(base_query(options).first!.attributes) }
26
+ run_and_convert_exceptions { entity_class(query(options).first!.attributes) }
27
27
  end
28
28
 
29
29
  def find_all(options = {})
30
- run_and_convert_exceptions { entity_class(base_query(options)) }
30
+ run_and_convert_exceptions { entity_class(query(options)) }
31
31
  end
32
32
 
33
33
  def create!(options = {})
@@ -55,13 +55,18 @@ module Horza
55
55
  end
56
56
  end
57
57
 
58
- def ancestors(options = {})
58
+ def association(options = {})
59
59
  run_and_convert_exceptions do
60
- result = walk_family_tree(@context.find(options[:id]), options)
60
+ options = Options.new(options)
61
61
 
62
+ base = @context
63
+ base = base.includes(options.eager_args) if options.eager_load?
64
+ base = base.find(options.id)
65
+
66
+ result = walk_family_tree(base, options)
62
67
  return nil unless result
63
68
 
64
- collection?(result) ? entity_class(result) : entity_class(result.attributes)
69
+ collection?(result) ? entity_class(query(options, result)) : entity_class(result.attributes)
65
70
  end
66
71
  end
67
72
 
@@ -73,8 +78,15 @@ module Horza
73
78
 
74
79
  private
75
80
 
76
- def base_query(options)
77
- @context.where(options).order('ID DESC')
81
+ def query(options, base = @context)
82
+ options = options.is_a?(Options) ? options : Options.new(options)
83
+
84
+ result = base
85
+ result = base.where(options.conditions) if options.conditions
86
+ result = result.order(base.arel_table[options.order_field].send(options.order_direction))
87
+ result = result.limit(options.limit) if options.limit
88
+ result = result.offset(options.offset) if options.offset
89
+ result
78
90
  end
79
91
 
80
92
  def collection?(subject = @context)
@@ -82,8 +94,9 @@ module Horza
82
94
  end
83
95
 
84
96
  def walk_family_tree(object, options)
85
- via = options[:via] || []
86
- via.push(options[:target]).reduce(object) do |object, relation|
97
+ via = options.via || []
98
+
99
+ via.push(options.target).reduce(object) do |object, relation|
87
100
  raise ::Horza::Errors::InvalidAncestry.new(INVALID_ANCESTRY_MSG) unless object.respond_to? relation
88
101
  object.send(relation)
89
102
  end
@@ -0,0 +1,45 @@
1
+ module Horza
2
+ module Adapters
3
+ class Options
4
+ META_METHODS = [:conditions, :limit, :offset, :order, :target, :id, :via]
5
+
6
+ def initialize(options)
7
+ @options = options
8
+ end
9
+
10
+ def method_missing(method)
11
+ super unless META_METHODS.include? method
12
+ @options[method]
13
+ end
14
+
15
+ def order_field
16
+ return :id unless order.present?
17
+ @options[:order].keys.first
18
+ end
19
+
20
+ def order_direction
21
+ return :desc unless order.present?
22
+
23
+ raise ::Horza::Errors::InvalidOption.new('Order must be :asc or :desc') unless [:asc, :desc].include?(@options[:order][order_field])
24
+ order[order_field]
25
+ end
26
+
27
+ def eager_load?
28
+ !!@options[:eager_load]
29
+ end
30
+
31
+ def eager_args
32
+ raise ::Horza::Errors::InvalidOption.new('You must pass eager_load: true and defined a target') unless eager_load? && target
33
+ return target unless via
34
+
35
+ via.reverse.reduce({}) do |hash, table|
36
+ if hash.empty?
37
+ hash.merge(table => target)
38
+ else
39
+ { table => hash }
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -21,16 +21,7 @@ module Horza
21
21
  end
22
22
 
23
23
  def adapter_map
24
- @adapter_map ||= generate_map
25
- end
26
-
27
- private
28
-
29
- def generate_map
30
- ::Horza::Adapters::AbstractAdapter.descendants.reduce({}) do |hash, (klass)|
31
- return hash unless klass.name
32
- hash.merge(klass.name.split('::').last.underscore.to_sym => klass)
33
- end
24
+ @adapter_map ||= ::Horza.descendants_map(::Horza::Adapters::AbstractAdapter)
34
25
  end
35
26
  end
36
27
 
@@ -12,6 +12,14 @@ module Horza
12
12
  def symbolize
13
13
  underscore.to_sym
14
14
  end
15
+
16
+ def underscore
17
+ gsub(/::/, '/')
18
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
19
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
20
+ .tr('-', '_')
21
+ .downcase
22
+ end
15
23
  end
16
24
  end
17
25
  end
data/lib/horza/errors.rb CHANGED
@@ -20,5 +20,8 @@ module Horza
20
20
 
21
21
  class RecordNotFound < StandardError
22
22
  end
23
+
24
+ class InvalidOption < StandardError
25
+ end
23
26
  end
24
27
  end
data/lib/horza.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'horza/adapters/class_methods'
2
2
  require 'horza/adapters/instance_methods'
3
+ require 'horza/adapters/options'
3
4
  require 'horza/adapters/abstract_adapter'
4
5
  require 'horza/adapters/active_record'
5
6
  require 'horza/core_extensions/string'
@@ -8,7 +9,7 @@ require 'horza/entities/collection'
8
9
  require 'horza/entities'
9
10
  require 'horza/configuration'
10
11
  require 'horza/errors'
11
- require 'active_support'
12
+ require 'active_support/inflections'
12
13
 
13
14
  module Horza
14
15
  extend Configuration
@@ -17,5 +18,9 @@ module Horza
17
18
  def descendants_map(klass)
18
19
  klass.descendants.reduce({}) { |hash, (klass)| hash.merge(klass.name.split('::').last.underscore.to_sym => klass) }
19
20
  end
21
+
22
+ def adapt(klass)
23
+ adapter.new(klass)
24
+ end
20
25
  end
21
26
  end
@@ -47,10 +47,10 @@ end
47
47
  describe Horza do
48
48
  let(:last_name) { 'Turner' }
49
49
  let(:adapter) { :active_record }
50
- let(:user_adapter) { Horza.adapter.new(HorzaSpec::User) }
51
- let(:customer_adapter) { Horza.adapter.new(HorzaSpec::Customer) }
52
- let(:employer_adapter) { Horza.adapter.new(HorzaSpec::Employer) }
53
- let(:sports_car_adapter) { Horza.adapter.new(HorzaSpec::SportsCar) }
50
+ let(:user_adapter) { Horza.adapt(HorzaSpec::User) }
51
+ let(:customer_adapter) { Horza.adapt(HorzaSpec::Customer) }
52
+ let(:employer_adapter) { Horza.adapt(HorzaSpec::Employer) }
53
+ let(:sports_car_adapter) { Horza.adapt(HorzaSpec::SportsCar) }
54
54
 
55
55
  # Reset base config with each iteration
56
56
  before { Horza.configure { |config| config.adapter = adapter } }
@@ -81,7 +81,17 @@ describe Horza do
81
81
  end
82
82
  end
83
83
 
84
- describe '#adapter' do
84
+ describe '#adapt' do
85
+ subject { Horza.adapt(HorzaSpec::User) }
86
+ it 'returns the adaptor class' do
87
+ expect(subject.is_a? Horza::Adapters::ActiveRecord).to be true
88
+ end
89
+ it 'sets the model as context' do
90
+ expect(subject.context).to eq HorzaSpec::User
91
+ end
92
+ end
93
+
94
+ describe 'Queries' do
85
95
  let(:user) { HorzaSpec::User.create }
86
96
 
87
97
  describe '#get!' do
@@ -119,17 +129,17 @@ describe Horza do
119
129
  2.times { HorzaSpec::User.create(last_name: 'OTHER') }
120
130
  end
121
131
  it 'returns single Entity' do
122
- expect(user_adapter.find_first(last_name: last_name).is_a? Horza::Entities::Single).to be true
132
+ expect(user_adapter.find_first(conditions: { last_name: last_name }).is_a? Horza::Entities::Single).to be true
123
133
  end
124
134
 
125
135
  it 'returns user' do
126
- expect(user_adapter.find_first!(last_name: last_name).to_h).to eq HorzaSpec::User.where(last_name: last_name).order('id DESC').first.attributes
136
+ expect(user_adapter.find_first!(conditions: { last_name: last_name }).to_h).to eq HorzaSpec::User.where(last_name: last_name).order('id DESC').first.attributes
127
137
  end
128
138
  end
129
139
 
130
140
  context 'when user does not exist' do
131
141
  it 'throws error' do
132
- expect { user_adapter.find_first!(last_name: last_name) }.to raise_error Horza::Errors::RecordNotFound
142
+ expect { user_adapter.find_first!(conditions: { last_name: last_name }) }.to raise_error Horza::Errors::RecordNotFound
133
143
  end
134
144
  end
135
145
  end
@@ -137,25 +147,45 @@ describe Horza do
137
147
  describe '#find_first' do
138
148
  context 'when user does not exist' do
139
149
  it 'returns nil' do
140
- expect(user_adapter.find_first(last_name: last_name)).to be nil
150
+ expect(user_adapter.find_first(conditions: { last_name: last_name })).to be nil
141
151
  end
142
152
  end
143
153
  end
144
154
 
145
155
  describe '#find_all' do
156
+ let(:conditions) { { last_name: last_name } }
157
+ let(:options) { { conditions: conditions } }
158
+
146
159
  context 'when users exist' do
147
160
  before do
148
- 3.times { HorzaSpec::User.create(last_name: last_name) }
161
+ 3.times { HorzaSpec::User.create(conditions) }
149
162
  2.times { HorzaSpec::User.create(last_name: 'OTHER') }
150
163
  end
151
164
  it 'returns user' do
152
- expect(user_adapter.find_all(last_name: last_name).length).to eq 3
165
+ expect(user_adapter.find_all(options).length).to eq 3
166
+ end
167
+
168
+ context 'with limit' do
169
+ it 'limits response' do
170
+ expect(user_adapter.find_all(options.merge(limit: 2)).length).to eq 2
171
+ end
172
+ end
173
+
174
+ context 'with offset' do
175
+ let(:total) { 20 }
176
+ let(:offset) { 7 }
177
+ before do
178
+ total.times { HorzaSpec::User.create(last_name: 'Smith') }
179
+ end
180
+ it 'offsets response' do
181
+ expect(user_adapter.find_all(conditions: { last_name: 'Smith' }, offset: offset).length).to eq total - offset
182
+ end
153
183
  end
154
184
  end
155
185
 
156
186
  context 'when user does not exist' do
157
187
  it 'throws error' do
158
- expect(user_adapter.find_all(last_name: last_name).empty?).to be true
188
+ expect(user_adapter.find_all(options).empty?).to be true
159
189
  end
160
190
  end
161
191
  end
@@ -262,7 +292,7 @@ describe Horza do
262
292
  end
263
293
  end
264
294
 
265
- context '#ancestors' do
295
+ context '#association' do
266
296
  context 'direct relation' do
267
297
  let(:employer) { HorzaSpec::Employer.create }
268
298
  let!(:user1) { HorzaSpec::User.create(employer: employer) }
@@ -270,36 +300,85 @@ describe Horza do
270
300
 
271
301
  context 'parent' do
272
302
  it 'returns parent' do
273
- expect(user_adapter.ancestors(id: user1.id, target: :employer).to_h).to eq employer.attributes
303
+ expect(user_adapter.association(id: user1.id, target: :employer).to_h).to eq employer.attributes
274
304
  end
275
305
  end
276
306
 
277
307
  context 'children' do
278
308
  it 'returns children' do
279
- result = employer_adapter.ancestors(id: employer.id, target: :users)
309
+ result = employer_adapter.association(id: employer.id, target: :users)
280
310
  expect(result.length).to eq 2
281
311
  expect(result.first.is_a? Horza::Entities::Single).to be true
282
- expect(result.first.to_hash).to eq HorzaSpec::User.order('id DESC').last.attributes
312
+ expect(result.first.to_hash).to eq HorzaSpec::User.order('id DESC').first.attributes
283
313
  end
284
314
  end
285
315
 
286
316
  context 'invalid ancestry' do
287
317
  it 'throws error' do
288
- expect { employer_adapter.ancestors(id: employer.id, target: :user) }.to raise_error Horza::Errors::InvalidAncestry
318
+ expect { employer_adapter.association(id: employer.id, target: :user) }.to raise_error Horza::Errors::InvalidAncestry
289
319
  end
290
320
  end
291
321
 
292
322
  context 'valid ancestry with no saved childred' do
293
323
  let(:employer2) { HorzaSpec::Employer.create }
294
324
  it 'returns empty collection error' do
295
- expect(employer_adapter.ancestors(id: employer2.id, target: :users).empty?).to be true
325
+ expect(employer_adapter.association(id: employer2.id, target: :users).empty?).to be true
296
326
  end
297
327
  end
298
328
 
299
329
  context 'valid ancestry with no saved parent' do
300
330
  let(:user2) { HorzaSpec::User.create }
301
331
  it 'returns nil' do
302
- expect(user_adapter.ancestors(id: user2.id, target: :employer)).to be nil
332
+ expect(user_adapter.association(id: user2.id, target: :employer)).to be nil
333
+ end
334
+ end
335
+
336
+ context 'with options' do
337
+ let(:turner_total) { 25 }
338
+ let(:other_total) { 20 }
339
+ let(:conditions) { { last_name: 'Turner' } }
340
+
341
+ before do
342
+ turner_total.times { employer.users << HorzaSpec::User.create(conditions.merge(employer: employer)) }
343
+ other_total.times { employer.users << HorzaSpec::User.create(employer: employer) }
344
+ end
345
+
346
+ context 'limit' do
347
+ it 'limits response' do
348
+ expect(employer_adapter.association(id: employer.id, target: :users, limit: 10).length).to eq 10
349
+ end
350
+ end
351
+
352
+ context 'conditions' do
353
+ it 'only returns matches' do
354
+ expect(employer_adapter.association(id: employer.id, target: :users, conditions: conditions).length).to eq turner_total
355
+ end
356
+ end
357
+
358
+ context 'offset' do
359
+ it 'offsets response' do
360
+ expect(employer_adapter.association(id: employer.id, target: :users, conditions: conditions, offset: 10).length).to eq turner_total - 10
361
+ end
362
+ end
363
+
364
+ context 'order' do
365
+ it 'orders response' do
366
+ horza_response = employer_adapter.association(id: employer.id, target: :users, conditions: conditions, order: { id: :asc })
367
+ ar_response = HorzaSpec::User.where(conditions).order('id asc')
368
+ expect(horza_response.first.id).to eq ar_response.first.id
369
+ expect(horza_response.last.id).to eq ar_response.last.id
370
+ end
371
+ end
372
+
373
+ context 'eager_load' do
374
+ context 'simple' do
375
+ it 'works as expected' do
376
+ horza_response = employer_adapter.association(id: employer.id, target: :users, conditions: conditions, order: { id: :asc }, eager_load: true)
377
+ ar_response = HorzaSpec::User.where(conditions).order('id asc')
378
+ expect(horza_response.first.id).to eq ar_response.first.id
379
+ expect(horza_response.last.id).to eq ar_response.last.id
380
+ end
381
+ end
303
382
  end
304
383
  end
305
384
  end
@@ -314,7 +393,14 @@ describe Horza do
314
393
  end
315
394
 
316
395
  it 'returns the correct ancestor' do
317
- expect(user_adapter.ancestors(id: user.id, target: :sports_cars, via: [:employer]).first).to eq sportscar.attributes
396
+ expect(user_adapter.association(id: user.id, target: :sports_cars, via: [:employer]).first).to eq sportscar.attributes
397
+ end
398
+
399
+ context 'with eager loading' do
400
+ it 'works as expected' do
401
+ horza_response = user_adapter.association(id: user.id, target: :sports_cars, via: [:employer], order: { id: :asc }, eager_load: true)
402
+ expect(horza_response.first.id).to eq sportscar.id
403
+ end
318
404
  end
319
405
  end
320
406
  end
data/spec/horza_spec.rb CHANGED
@@ -11,7 +11,10 @@ describe Horza do
11
11
  end
12
12
 
13
13
  context 'when adapter is configured' do
14
- before { Horza.configure { |config| config.adapter = :active_record } }
14
+ before do
15
+ Horza.reset
16
+ Horza.configure { |config| config.adapter = :active_record }
17
+ end
15
18
  after { Horza.reset }
16
19
  it 'returns appropriate class' do
17
20
  expect(Horza.adapter).to eq Horza::Adapters::ActiveRecord
@@ -19,3 +22,138 @@ describe Horza do
19
22
  end
20
23
  end
21
24
  end
25
+
26
+ describe Horza::Adapters::Options do
27
+ subject { Horza::Adapters::Options.new(options) }
28
+
29
+ context 'when all options are defined' do
30
+ let(:options) do
31
+ {
32
+ conditions: { last_name: 'Turner' },
33
+ order: { last_name: :asc },
34
+ limit: 20,
35
+ offset: 10,
36
+ target: :sports_cars,
37
+ via: [:employer],
38
+ eager_load: true
39
+ }
40
+ end
41
+
42
+ Horza::Adapters::Options::META_METHODS.each do |method|
43
+ context "##{method}" do
44
+ it 'returns conditions' do
45
+ expect(subject.send(method)).to eq options[method]
46
+ end
47
+ end
48
+ end
49
+
50
+ context '#order_field' do
51
+ context 'when order is passed' do
52
+ it 'returns key of options hash' do
53
+ expect(subject.order_field).to eq(:last_name)
54
+ end
55
+ end
56
+
57
+ context 'when order is not passed' do
58
+ let(:options) { { conditions: { last_name: 'Turner' } } }
59
+ it 'defaults to id' do
60
+ expect(subject.order_field).to eq(:id)
61
+ end
62
+ end
63
+ end
64
+
65
+ context '#order_direction' do
66
+ context 'when order is passed' do
67
+ it 'returns key of options hash' do
68
+ expect(subject.order_direction).to eq(:asc)
69
+ end
70
+ end
71
+
72
+ context 'when order is not passed' do
73
+ let(:options) { { conditions: { last_name: 'Turner' } } }
74
+ it 'defaults to desc' do
75
+ expect(subject.order_direction).to eq(:desc)
76
+ end
77
+ end
78
+ end
79
+
80
+ context '#eager_load?' do
81
+ context 'when eager_load is true' do
82
+ it 'returns true' do
83
+ expect(subject.eager_load?).to be true
84
+ end
85
+ end
86
+
87
+ context 'when eager_load is not set' do
88
+ let(:options) { { conditions: { last_name: 'Turner' } } }
89
+ it 'returns false' do
90
+ expect(subject.eager_load?).to be false
91
+ end
92
+ end
93
+ end
94
+
95
+ context '#eager_args' do
96
+ context 'when eager_load is false' do
97
+ let(:options) { { conditions: { last_name: 'Turner' } } }
98
+ it 'raises error' do
99
+ expect { subject.eager_args }.to raise_error Horza::Errors::InvalidOption
100
+ end
101
+ end
102
+
103
+ context 'simple relation' do
104
+ let(:options) do
105
+ {
106
+ id: 999,
107
+ target: :users,
108
+ eager_load: true
109
+ }
110
+ end
111
+ it 'returns target' do
112
+ expect(subject.eager_args).to eq :users
113
+ end
114
+ end
115
+
116
+ context '1 via' do
117
+ let(:options) do
118
+ {
119
+ id: 999,
120
+ target: :sports_cars,
121
+ via: [:employer],
122
+ eager_load: true
123
+ }
124
+ end
125
+ it 'returns target as value, via as key' do
126
+ expect(subject.eager_args).to eq(employer: :sports_cars)
127
+ end
128
+ end
129
+
130
+ context '2 vias' do
131
+ let(:options) do
132
+ {
133
+ id: 999,
134
+ target: :sports_cars,
135
+ via: [:user, :employer],
136
+ eager_load: true
137
+ }
138
+ end
139
+ it 'returns target as value, final as key, nested in first via' do
140
+ expect(subject.eager_args).to eq(user: { employer: :sports_cars })
141
+ end
142
+ end
143
+
144
+ context '3 vias' do
145
+ let(:options) do
146
+ {
147
+ id: 999,
148
+ target: :sports_cars,
149
+ via: [:app, :user, :employer],
150
+ eager_load: true
151
+ }
152
+ end
153
+ it 'returns target as value, final as key, nested in first via' do
154
+ expect(subject.eager_args).to eq(app: { user: { employer: :sports_cars } })
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: horza
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
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-06-05 00:00:00.000000000 Z
11
+ date: 2015-06-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hashie
@@ -108,6 +108,7 @@ files:
108
108
  - lib/horza/adapters/active_record.rb
109
109
  - lib/horza/adapters/class_methods.rb
110
110
  - lib/horza/adapters/instance_methods.rb
111
+ - lib/horza/adapters/options.rb
111
112
  - lib/horza/configuration.rb
112
113
  - lib/horza/core_extensions/string.rb
113
114
  - lib/horza/entities.rb