Created
October 18, 2012 21:26
-
-
Save kneath/3914835 to your computer and use it in GitHub Desktop.
Given a controller in need of refactoring into multiple controllers, how can I redirect to new controller actions based upon a feature flag?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Given a controller in need of refactoring into multiple controllers, how | |
# can I redirect to new controller actions based upon a feature flag? | |
# | |
# The current code "works" but doesn't exercise the controller action. | |
# | |
# Rails 2.3 or 3.0 methods accepted | |
class BetterController | |
def overview | |
# .. a small amount of auth/permissions code | |
end | |
end | |
class PoorlyNamedController | |
def show | |
if feature_flag? | |
render :template => 'better/overview', :layout => 'new_layout' | |
return | |
end | |
# ... tons of code here in a horrible method that needs to be split | |
# into multiple methods across many controllers | |
end | |
end |
# This is NOT to be meant for constant use, but is useful when you want
# to refactor a controller method into many controllers or into an action
# in another controller and want to do it staff-only for a while.
#
# controller - The controller Class you wish to render.
# action - The controller action Symbol you wish to render.
def render_in_controller(controller, action)
c = controller.new
c.request = @_request
c.response = @_response
c.params = params
c.process(action)
c.response.body
end
def index
render :inline => render_in_controller(TestersController, 'index')
return
end
This works with 2.3: http://www.railsonwave.com/2008/10/25/how-to-call-a-controller-s-action-from-a-different-controller
I had to change Inflector
to ActiveSupport::Inflector
for it to work for me though.
Man that's reallly close. Still it's trying to call the same action name (not the action name I'm sending it). I added the action name into the .process call in request, response, options[:action]
but still wants the same name.
Thanks a ton though, this is getting very close!
def internal_redirect_to(options={})
params.merge!(options)
request.env['action_controller.request.path_parameters']['controller'] = params[:controller]
request.env['action_controller.request.path_parameters']['action'] = params[:action]
(c = ActionController.const_get(ActiveSupport::Inflector.classify("#{params[:controller]}_controller")).new).process(request,response)
c.instance_variables.each{|v| self.instance_variable_set(v,c.instance_variable_get(v))}
end
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
So what I have right now gets very close, unfortunately this app is in the middle of being both Rails 2.GitHub and Rails 3.GitHub, so it's hard to nail down what's going on.
This works, except the response body is always nil. Calling
render :template => 'better/overview'
after callingrender_in_controller
works exactly as expected. I'd just love if it let the controller action figure out what to render.