45

Does anyone know why I get

undefined method `my_method' for #<MyController:0x1043a7410>

when I call my_method("string") from within my ApplicationController subclass? My controller looks like

class MyController < ApplicationController
  def show
    @value = my_method(params[:string])
  end
end

and my helper

module ApplicationHelper
  def my_method(string)
    return string
  end
end

and finally, ApplicationController

class ApplicationController < ActionController::Base
  after_filter :set_content_type
  helper :all
  helper_method :current_user_session, :current_user
  filter_parameter_logging :password
  protect_from_forgery # See ActionController::RequestForgeryProtection for details
1

12 Answers 12

62

You cannot call helpers from controllers. Your best bet is to create the method in ApplicationController if it needs to be used in multiple controllers.

EDIT: to be clear, I think a lot of the confusion (correct me if I'm wrong) stems from the helper :all call. helper :all really just includes all of your helpers for use under any controller on the view side. In much earlier versions of Rails, the namespacing of the helpers determined which controllers' views could use the helpers.

I hope this helps.

Sign up to request clarification or add additional context in comments.

2 Comments

Good information. I actually ended creating a module for my method, as promoted in the following thread, since the method is pretty generic (it converts a string to be url safe) and shouldn't be specific to controllers: stackoverflow.com/questions/128450/…
This is a good answer, but I would expand on it a bit further. helper_method when used in the Controller adds a method that exist in the controller to the corresponding helper. i.e. method in Application Controller gets added to ApplicationHelper. This doesn't work the other way.
34

view_context is your friend, http://apidock.com/rails/AbstractController/Rendering/view_context

if you wanna share methods between controller and view you have further options:

2 Comments

Defining the methods in a shared module is a good way to go...since helpers are automatically included in Rails views.
It should be marked has the correct answer because this bring the solution to the problem. But a little explanation like @theIV did could also help. :-)
30

Include ApplicationHelper in application_controller.rb file like this:

class ApplicationController < ActionController::Base
  protect_from_forgery       
  include ApplicationHelper  
end

This way all the methods defined in application_helper.rb file will be available in the controller.

You can also include individual helpers in individual controllers.

1 Comment

Wow, this is working if some one wants to use ApplicationHelper method in other controllers or view just add this include ApplicationHelper .
7

Maybe I'm wrong, but aren't the helpers just for views? Usually if you need a function in a controller, you put it into ApplicationController as every function there is available in its childclasses.

3 Comments

Hm, that sucks. I wish I could use methods in both controllers and views. Oh well.
You can, kind of... Your helper_method call is giving you access to those methods in your views.
I have a helper that have to be used in the view and in the controller when rendering json with recursive tree, and I can't use it in controller?
6

As said by gamecreature in this post:

  • In Rails 2 use the @template variable.
  • In Rails 3 use the controller method view_context

Comments

4

helpers are for views, but adding a line of code to include that helper file in ApplicationController.rb can take care of your problem. in your case, insert the following line in ApplicationController.rb:

include ApplicationHelper

Comments

3

As far as i know, helper :all makes the helpers available in the views...

Comments

3

Try appending module_function(*instance_methods) in your helper modules, after which you could directly call those methods on the module itself.

Comments

1

though its not a good practice to call helpers in controller since helpers are meant to be used at views the best way to use the helpers in controller is to make a helper method in application_controller and call them to the controller,
but even if it is required to call the helper in a controller
then Just include the helper in the controller

class ControllerName < ApplicationController
  include HelperName
  ...callback statements..

and call the helper methods directly to the controller

 module OffersHelper
  def generate_qr_code(text)
    require 'barby'
    require 'barby/barcode'
    require 'barby/barcode/qr_code'
    require 'barby/outputter/png_outputter'
    barcode = Barby::QrCode.new(text, level: :q, size: 5)
    base64_output = Base64.encode64(barcode.to_png({ xdim: 5 }))
    "data:image/png;base64,#{base64_output}"
  end

Controller

class ControllerName < ApplicationController
include OffersHelper

def new
  generate_qr_code('Example Text')
end
end

hope this helps !

Comments

0

I had the same problem...

you can hack/bodge around it, put that logic into a model, or make a class specially for it. Models are accessible to controllers, unlike those pesky helper methods.

Here is my "rag.rb" model

class Rag < ActiveRecord::Base
  belongs_to :report
  def miaow()
    cat = "catattack"
  end  
end

Here is part of my "rags_controller.rb" controller

def update
  @rag = Rag.find(params[:id])
  puts @rag.miaow()
  ...

This gave a catattack on the terminal, after I clicked "update".

Given an instantiation, methods in the model can be called. Replace catattack with some codes. (This is the best I have so far)

:helper all only opens helpers up to views.

This shows how to make a class and call it. http://railscasts.com/episodes/101-refactoring-out-helper-object?autoplay=true

Comments

0

Try this to access helper function directly from your controllers view_context.helper_name

Comments

0

You can include your helper methods into a controller with a helper keyword syntax

class MyController < ApplicationController
  helper ApplicationHelper

end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.