Matthew Clark
Matthew Clark

Reputation: 1965

Call a controller's method in other controllers (staying DRY)

I'm slightly new to Rails (i.e. stupid and need some teachin').

I have a controller (call it ControllerFoo) that performs a particular task (theMethod) which could be useful in other controllers (say, from within ControllerBar). So, of course, the method is defined as self.theMethod in ControllerFoo (which means it's a class method, right?), and access in ControllerBar as ControllerFoo.theMethod. Confused yet?

Here's the problem: the ControllerFoo.theMethod uses session data, and when called from ControllerBar, session is nil. In fact, it seems that session is also nil when being called from itself. I guess what I'm saying is class methods can't access session data?

<rant>I hate how session data can't simply be accessed anywhere like in PHP</rant>

So for now, since I'm not smart enough to know how to do this correctly, I've just duplicated the logic in several places throughout my app. But this is not DRY at all, and I hate it.

So how can I create a method in a controller that's accessible to other controllers and can also access session data?

class ControllerFoo < ApplicationController
    def self.theMethod (greeting)
        p "#{greeting} #{session[:user]}!"
    end
end

class ControllerBar < ApplicationController
    def show
        ControllerFoo.theMethod("Hello,")
    end
end

Upvotes: 1

Views: 2635

Answers (2)

ennuikiller
ennuikiller

Reputation: 46965

The way you would do this is Ruby would be to create a module containing the class (or instance) methods you wish to share and include it in the classes you need to have those methods defined in.

Upvotes: 1

Rob Di Marco
Rob Di Marco

Reputation: 44952

Couple of options...

  1. Put the shared method in the shared parent ApplicationController
  2. Create a module that both ControllerFoo and ControllerBar will include

e.g.

module SharedModule
    def theMethod (greeting)
        p "#{greeting} #{session[:user]}!"
    end
end
class ControllerFoo < ApplicationController
    include SharedModule
end

class ControllerBar < ApplicationController
    include SharedModule
    def show
        theMethod("Hello,")
    end
end

Upvotes: 5

Related Questions