Skip to content

Commit

Permalink
Merge pull request #28 from pabloh/preload_model_on_context
Browse files Browse the repository at this point in the history
Preload model on context
  • Loading branch information
pabloh committed May 21, 2018
2 parents 56bcb70 + ef064c0 commit d37bfb0
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 27 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
## [0.6.2] - 2018-05-19
## [0.7.0] - 2018-05-21
### Changed
- `sequel_models` plugin now automatically adds an optional context parameter to preload the model and avoid hitting the db on `:fetch_model` when the model is already available.
- Add `:set_context_param` option for `sequel_models` plugin to prevent adding the context parameter to preload the model into the context.

## [0.6.2] - 2018-05-19
### Fixes
- Allow `:error_message` option for `sequel_models` plugin to propagate down inherited classes

## [0.6.1] - 2018-03-16
Expand Down
4 changes: 3 additions & 1 deletion lib/pathway/plugins/sequel_models.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ def after_commit(&bl)
module ClassMethods
attr_accessor :model_class, :search_field, :model_not_found

def model(model_class, search_by: model_class.primary_key, set_result_key: true, error_message: nil)
def model(model_class, search_by: model_class.primary_key, set_result_key: true, set_context_param: true, error_message: nil)
self.model_class = model_class
self.search_field = search_by
self.result_key = Inflector.underscore(Inflector.demodulize(model_class.name)).to_sym if set_result_key
self.model_not_found = error_message || "#{Inflector.humanize(Inflector.underscore(Inflector.demodulize(model_class.name)))} not found".freeze

self.context(result_key => Contextualizer::OPTIONAL) if set_result_key && set_context_param
end

def inherited(subclass)
Expand Down
2 changes: 1 addition & 1 deletion lib/pathway/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Pathway
VERSION = '0.6.2'
VERSION = '0.7.0'
end
4 changes: 2 additions & 2 deletions pathway.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ Gem::Specification.new do |spec|

spec.required_ruby_version = ">= 2.4.0"

spec.add_dependency "dry-inflector", ">= 0.1.1"
spec.add_dependency "contextualizer", "~> 0.0.3"
spec.add_dependency "dry-inflector", ">= 0.1.0"
spec.add_dependency "contextualizer", "~> 0.0.4"

spec.add_development_dependency "dry-validation", "~> 0.11"
spec.add_development_dependency "bundler", ">= 1.14.0"
Expand Down
46 changes: 24 additions & 22 deletions spec/plugins/sequel_models_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ class SubOperation < MyOperation; end
let(:mailer) { double.tap { |d| allow(d).to receive(:send_emails) } }
let(:operation) { MyOperation.new(mailer: mailer) }

describe "DSL" do
describe 'DSL' do
let(:result) { operation.call(params) }
let(:params) { { email: 'asd@fgh.net' } }
let(:model) { double }

describe "#transaction" do
it "returns the result state provided by the inner transaction when successful" do
describe '#transaction' do
it 'returns the result state provided by the inner transaction when successful' do
allow(MyModel).to receive(:first).with(params).and_return(model)

expect(result).to be_a_success
Expand All @@ -57,15 +57,15 @@ class SubOperation < MyOperation; end
end
end

describe "#after_commit" do
it "calls after_commit block when transaction is successful" do
describe '#after_commit' do
it 'calls after_commit block when transaction is successful' do
allow(MyModel).to receive(:first).with(params).and_return(model)
expect(mailer).to receive(:send_emails).with(model)

expect(result).to be_a_success
end

it "does not call after_commit block when transaction fails" do
it 'does not call after_commit block when transaction fails' do
allow(MyModel).to receive(:first).with(params).and_return(nil)

expect(mailer).to_not receive(:send_emails)
Expand Down Expand Up @@ -115,7 +115,7 @@ class SubOperation < MyOperation; end
end
end

let(:key) { "some@email.com" }
let(:key) { 'some@email.com' }
let(:params) { { foo: 3, bar: 4} }

describe '#find_model_with' do
Expand Down Expand Up @@ -195,54 +195,56 @@ class SubOperation < MyOperation; end
end

describe '#call' do
class CtxOperation < MyOperation
context my_model: nil
end

let(:operation) { CtxOperation.new(ctx) }
let(:operation) { MyOperation.new(ctx) }
let(:result) { operation.call(email: 'an@email.com') }
let(:fetched_model) { MyModel.new }

context "when the model is not present at the context" do
context 'when the model is not present at the context' do
let(:ctx) { {} }
it "fetchs the model from the DB" do

it "doesn't include the model's key on the operation's context" do
expect(operation.context).to_not include(:my_model)
end
it 'fetchs the model from the DB' do
expect(MyModel).to receive(:first).with(email: 'an@email.com').and_return(fetched_model)

expect(result.value).to be(fetched_model)
end
end

context "when the model is already present in the context" do
context 'when the model is already present in the context' do
let(:existing_model) { MyModel.new }
let(:ctx) { { my_model: existing_model } }

it "uses the model from the context and avoid querying the DB" do
it "includes the model's key on the operation's context" do
expect(operation.context).to include(my_model: existing_model)
end
it 'uses the model from the context and avoid querying the DB' do
expect(MyModel).to_not receive(:first)

expect(result.value).to be(existing_model)
end

context "but overwrite: option in step is true" do
class OwOperation < CtxOperation
context my_model: nil

context 'but :fetch_model step specifies overwrite: true' do
class OwOperation < MyOperation
process do
step :fetch_model, overwrite: true
end
end

let(:operation) { OwOperation.new(ctx) }

it "fetches the model from the DB anyway" do
it 'fetches the model from the DB anyway' do
expect(MyModel).to receive(:first).with(email: 'an@email.com').and_return(fetched_model)

expect(operation.context).to include(my_model: existing_model)
expect(operation.my_model).to be(existing_model)
expect(result.value).to be(fetched_model)
end
end
end
end
end

end
end
end

0 comments on commit d37bfb0

Please sign in to comment.