Having a controller action call an action in a different controller

Does anyone know how to go about having a controller action call an
action in a completely different controller?

The reason for wanting to do this is that my Rails app has several
actions that are common across all pages (these actions are part of
the page layout, and these pages are produced by several different
controllers). These actions modify the database. The app uses Ajax
heavily to update the current page rather than performing a complete
page refresh. The logic to update the current page is specific to the
controller that originated the page. My rjs templates for the common
actions currently have lots of conditional logic in them (for handling
all the different pages that a common action can be called from), so
I’m trying to find a better way of doing this (the current approach is
not object oriented and is getting difficult to maintain).

So, the pattern I would like to use is to have the common actions
handled by a controller that knows how to update the database (but is
view agnostic), and then delegating the rendering responsibilities
(i.e. generate JavaScript via RJS for updating the current page) to
the controller that originated the page. This is where the idea of
having one controller call another controller comes into play.

Here is a contrived example that demonstrates what I’m trying to
accomplish:

Controller that allows a user to view and interact with widgets

class WidgetViewController < ApplicationController
def all_widgets # action that returns a list of all widgets
# logic to set up the all_widgets rjs for displaying list of
widgets

    # save off the controller and action which produced this view
    session[:current_controller] = "WidgetViewController"
    session[:current_action] = "all_widgets"
end

def refresh_all_widgets
    # logic to set up the refresh_all_widgets rjs for refreshing

the current page
end

def recent_widgets  # action that returns a list of widgets

recently created
# logic to set up the recent_widgets rjs for displaying list
of recently created widgets

    # save off the controller and action which produced this view
    session[:current_controller] = "WidgetViewController"
    session[:current_action] = "recent_widgets"
end

def refresh_recent_widgets
    # logic to set up the refresh_recent_widgets rjs for

refreshing the current page
end
end

Controller that handles common actions related to creating, editing

and deleting widget models
class WidgetController < ApplicationController
def create # creates a widget in the database
widget = Widget.new(params[:widget])
if ( widget.save() )
# delegate rendering responsibility to controller that
originated the current page
controller_class = eval(session[:current_controller])
controller = controller_class.new
controller_refresh_action =
“refresh_#{session[:current_action]}”
controller.send(controller_refresh_action) # call the
“refresh” action to delegate rendering responsibilities
else
# appropriate error handling
end
end
end

The code above does end up calling the appropriate “refresh” action in
the WidgetViewController, however it crashes down inside of Rails when
trying to render that action. After digging into how Rails spins up a
controller to service a request, I can see why this isn’t working -
after instantiating a controller, Rails performs set up on the
controller, and then passes it request and response objects.

Thanks in advance,
Denis

On 28 Feb 2008, at 14:47, denisa wrote:

controller that originated the page. My rjs templates for the common
having one controller call another controller comes into play.
I very much recommend you don’t do this. The common databasey stuff
should be in models, you can share presentation stuff via helpers and
shared partials.

Fred

If you want to consolidate the retrieval of data that’s necessary for
the widgets to be displayed, it sounds like you want to abstract that
into a module that you can include into your controller. From there,
as Fred suggests, use partials and helpers to do the rendering.

On Feb 28, 9:58 am, Frederick C. [email protected]

Here is a concrete example of how to create a class to help you render
the same HTML content in different views, althought it doesn’t access
the database.

http://railscasts.com/episodes/101

Another thing that helps display related models in a different view
is the plugin called attribute_fu.

http://jamesgolick.com/tags/attribute_fu

I guess the million dollar question is:

How do you access a totally different unrelated model/data/
controller in a totally different view?

For that, I think you would probably create something like the first
example, but put it in the /lib directory and have it access the model
of interest. Does anybody have a good concrete example of this
online?

Hope this helps.

David :slight_smile:

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs