Skip to content

Adding new actions in a controller from a Helper

leucos edited this page Oct 2, 2012 · 1 revision

Adding an action means that the method mixed in the controller will be reachable via URL routing. There is at least two ways to add new actions from a Helper.

The "Hard" Way

If you define methods using class_eval, they will "belong" to the controller (and not from the mixed-in helper) and thus will be available as actions.

In the following example, we define a add method in the controller from our Hardculator helper :

module Ramaze
  module Helper
    module Hardculator
      def self.included(c)
        c.class_eval {
          define_method(:add) { |*args|
            args.map(&:to_i).inject(:+)
          }
        }
      end
    end
  end
end

self.included is a hook that will be called when the Hardculator module is mixed in the controller's class. The c argument is the controller's Class. We can then ask c to class_eval the definition of a new method (:add) that just sums the arguments it receives.

Now, when /controller/add/1/2/3/4 is invoked, the action will return 10 (see the complete example in the bottom of the page).

The Easy Way (© manveru)

The other way is to use the EXPOSE Set in Ramaze::Helper : all the modules listed in this Set will be exposed as actions in the controller that mixes them in.

In the following example, we define a add method in the controller from our Easyculator helper :

module Ramaze
  module Helper
    module Easyculator
      # Expose helper methods as actions
      Ramaze::Helper::EXPOSE << self

      def add(*args)
        args.map(&:to_i).inject(:+)
      end
    end
  end
end

Pros & Cons

  • The Easy Way :

  • pros : it's straightforward

  • cons : it makes all the modules method's available as acxtions (this might not be what you want)

  • The "Hard" way :

  • pros : you can choose specifically what new actions yu can to add

  • cons : less readable

Complete self-contained example

require 'ramaze'

# Helpers
module Ramaze
  module Helper

    module Hardculator
      def self.included(c)
        c.class_eval {
          define_method(:add) { |*args|
            args.map(&:to_i).inject(:+)
          }
        }
      end
    end

    module Easyculator
      # Expose helper methods as actions
      Ramaze::Helper::EXPOSE << self

      def add(*args)
        args.map(&:to_i).inject(:+)
      end
    end

  end
end

# Controllers
class Easy < Ramaze::Controller
  layout nil
  helper :easyculator
end

class Hard < Ramaze::Controller
  layout nil
  helper :hardculator
end

Ramaze.start

Save as app.rb and run ruby app.rb.

Try to fetch the new actions with curl :

curl http://localhost:7000/easy/add/1/2/3 => 6

curl http://localhost:7000/hard/add/1/2/3 => 6

Have fun !

Clone this wiki locally