I reasoned that placing an action in the application controller would
be roughly equivalent to placing that action in each of the other
controllers since each of the other controllers inherits from the
application controller. It turns out that that doesn't work. It
behaves as if the action is missing from the other controllers. I
thinking that, for whatever reason, when Rails looks for an action it
only looks at the controller and doesn't look up the chain. If the
action isn't there, it behaves accordingly. Can anyone tell me why
that is and what I should do about it if I want the action in the
application controller to be available in several other controllers?
Since all controllers are inherited from ApplicationController,
methods of ApplicetionController are only inherited as "methods" and
not as "actions". You can use these inherited methods like normal
methods, but you can not use them as "actions" (i.e., methods that are
executed upon a request via routing).
Requiring the same action for multiple controllers is quite uncommon,
there may be better methods to do the same thing.
But still you can use this -
class ApplicationController < ActionController::Base
def common_action
#code
end
end
class ExampleController < ApplicationController
def common_action
super
#render 'shared/common_action' #uncomment this line if you want to
use a common template too.
end
end
Requiring the same action for multiple controllers is quite uncommon,
there may be better methods to do the same thing.
Believe me, when someone tells me something like that, I listen
because the person speaking is usually right. I really want to avoid
doing things in an unorthodox way and/or in a way that makes things
more difficult than they need to be. Perhaps the problem is that I
have too many controllers. In this case, I have a 'main' controller
for general purpose actions and an 'admin' controller for
administrative actions. Access to the admin controller is limited to
the admin user. The action in question provides a gateway to all of
the CRUD capabilities; however, I want only the administrative user to
have access to the CUD capabilities. In addition, the views are also
different because the admin view includes the CUD capabilities. Given
these circumstances, I thought it would be nice to have a copy of this
action in both the admin controller and the main controller. But, I
want to keep my code DRY. So, it seemed to me that the logical thing
to do would be to place the action in the application controller and
let it inherit down to both the main and admin controllers. It seems
to work just fine. Do you still think that I'm on the wrong track?
What I understood from your text is that “Reading” is common for both Main and Admin. If the common code is totally database specific, you should be using a class method of the model instead. And just call it in action like, say,