From 387878f39c403c4b2fced56704ca9832ba5395f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Bu=C5=82at?= Date: Mon, 8 May 2017 16:23:13 +0200 Subject: [PATCH] Clean view context when controller changes (#799) When we reassign controller it is the right thing to do to clear current view context stored in request store. Consider a case when view context was built before the request was made (usage of `h` helper in class level context). View context is built from default controller and has no information about the request. During first request `Draper::ViewContext.current.controller` will be different than `Draper::ViewContext.controller`. --- lib/draper/view_context.rb | 4 +++- spec/draper/view_context_spec.rb | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/draper/view_context.rb b/lib/draper/view_context.rb index 9634d25..d0d05bb 100644 --- a/lib/draper/view_context.rb +++ b/lib/draper/view_context.rb @@ -20,8 +20,10 @@ module Draper RequestStore.store[:current_controller] end - # Sets the current controller. + # Sets the current controller. Clears view context when we are setting + # different controller. def self.controller=(controller) + clear! if RequestStore.store[:current_controller] != controller RequestStore.store[:current_controller] = controller end diff --git a/spec/draper/view_context_spec.rb b/spec/draper/view_context_spec.rb index 1816cd1..e62008c 100644 --- a/spec/draper/view_context_spec.rb +++ b/spec/draper/view_context_spec.rb @@ -32,6 +32,34 @@ module Draper ViewContext.controller = :stored_controller expect(store[:current_controller]).to be :stored_controller end + + it "cleans context when controller changes" do + store = { + current_controller: :stored_controller, + current_view_context: :stored_view_context + } + + allow(RequestStore).to receive_messages store: store + + ViewContext.controller = :other_stored_controller + + expect(store).to include(current_controller: :other_stored_controller) + expect(store).not_to include(:current_view_context) + end + + it "doesn't clean context when controller is the same" do + store = { + current_controller: :stored_controller, + current_view_context: :stored_view_context + } + + allow(RequestStore).to receive_messages store: store + + ViewContext.controller = :stored_controller + + expect(store).to include(current_controller: :stored_controller) + expect(store).to include(current_view_context: :stored_view_context) + end end describe ".current" do