Skip to content

Commit 9b4e484

Browse files
committed
Allow caller to provide a custom data-mapper
1 parent ffd0bf2 commit 9b4e484

6 files changed

Lines changed: 51 additions & 4 deletions

File tree

lib/brainstem/presenter_collection.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def initialize
3333
# @option options [Boolean] :apply_default_filters Determine if Presenter's filter defaults should be applied. On by default.
3434
# @option options [Brainstem::Presenter] :primary_presenter The Presenter to use for filters and sorts. If unspecified, the +:model+ or +name+ will be used to find an appropriate Presenter.
3535
# @option options [paginator] :paginator Optional custom paginator. If unspecified, the default paginator will be used.
36+
# @option options [data_mapper] :paginator Optional custom data mapper. If unspecified, the default data mapper will be used.
3637
# @yield Must return a scope on the model +name+, which will then be presented.
3738
# @return [Hash] A hash of arrays of hashes. Top-level hash keys are pluralized model names, with values of arrays containing one hash per object that was found by the given given options.
3839
def presenting(name, options = {}, &block)

lib/brainstem/query_strategies/base_strategy.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def paginator
8383
end
8484

8585
def data_mapper
86-
Brainstem::QueryStrategies::DataMapper.new
86+
@data_mapper ||= @options[:data_mapper] || Brainstem::QueryStrategies::DataMapper.new
8787
end
8888
end
8989
end

lib/brainstem/query_strategies/data_mapper.rb

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,20 @@ module Brainstem
22
module QueryStrategies
33
class DataMapper
44
def get_models(ids:, scope:)
5-
id_lookup = {}
6-
ids.each.with_index { |id, index| id_lookup[id] = index }
7-
scope.klass.where(id: ids).sort_by { |model| id_lookup[model.id] }
5+
models = _get_models(scope, ids)
6+
sort_models(models, ids)
7+
end
8+
9+
private
10+
11+
def _get_models(scope, ids)
12+
scope.klass.where(id: ids)
13+
end
14+
15+
def sort_models(models, ids)
16+
model_order = {}
17+
ids.each.with_index { |id, index| model_order[id] = index }
18+
models.sort_by { |model| model_order[model.id] }
819
end
920
end
1021
end
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
require "spec_helper"
2+
3+
describe Brainstem::QueryStrategies::DataMapper do
4+
describe "#get_models" do
5+
it 'gets all models in the ids list sorted by list order, not the scope' do
6+
scope = Workspace.order(:id).limit(10)
7+
ids = scope.map(&:id).shuffle
8+
expect(ids.length).to be > 3
9+
10+
models = subject.get_models(ids: ids, scope: scope)
11+
expect(models.map(&:id)).to eq ids
12+
end
13+
end
14+
end

spec/brainstem/query_strategies/filter_and_search_spec.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,17 @@ def run_query
6363
end
6464
end
6565

66+
context 'when options contain a data_mapper' do
67+
let(:data_mapper) { Object.new }
68+
let(:options) { default_options.merge(data_mapper: data_mapper) }
69+
70+
it 'uses the provided data_mapper' do
71+
mock(data_mapper).get_models(anything) { [] }
72+
query_strategy = described_class.new(options)
73+
query_strategy.execute(Workspace.unscoped)
74+
end
75+
end
76+
6677
context 'with limit and offset params' do
6778
let(:limit) { 2 }
6879
let(:offset) { 4 }

spec/brainstem/query_strategies/filter_or_search_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,16 @@
5555
subject.execute(Workspace.unscoped)
5656
end
5757
end
58+
59+
context 'when options contain a data_mapper' do
60+
let(:data_mapper) { Object.new }
61+
let(:options) { default_options.merge(data_mapper: data_mapper) }
62+
63+
it 'uses the provided data_mapper' do
64+
mock(data_mapper).get_models(anything) { [] }
65+
subject.execute(Workspace.unscoped)
66+
end
67+
end
5868
end
5969
end
6070
end

0 commit comments

Comments
 (0)