"неопределенный метод" при вызове вспомогательного метода из контроллера в Rails - PullRequest
40 голосов
/ 05 марта 2010

Кто-нибудь знает, почему я получаю

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

когда я вызываю my_method ("string") из моего подкласса ApplicationController? Мой контроллер выглядит как

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

и мой помощник

module ApplicationHelper
  def my_method(string)
    return string
  end
end

и, наконец, 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

Ответы [ 11 ]

61 голосов
/ 05 марта 2010

Вы не можете вызывать помощников из контроллеров. Лучше всего создать метод в ApplicationController, если его необходимо использовать в нескольких контроллерах.

РЕДАКТИРОВАТЬ : для ясности, я думаю, что большая путаница (поправьте меня, если я ошибаюсь) связана с вызовом helper :all. helper :all действительно включает в себя все ваши помощники для использования под любым контроллером на стороне обзора. В гораздо более ранних версиях Rails пространство имен помощников определяло, какие представления контроллеров могут использовать помощники.

Надеюсь, это поможет.

33 голосов
/ 17 июня 2011

view_context - ваш друг, http://apidock.com/rails/AbstractController/Rendering/view_context

если вы хотите поделиться методами между контроллером и представлением, у вас есть дополнительные опции:

25 голосов
/ 26 мая 2011

Включите ApplicationHelper в файл application_controller.rb следующим образом:

class ApplicationController < ActionController::Base
  protect_from_forgery       
  include ApplicationHelper  
end

Таким образом, все методы, определенные в файле application_helper.rb, будут доступны в контроллере.

Вы также можете включить отдельных помощников в отдельные контроллеры.

7 голосов
/ 05 марта 2010

Может быть, я ошибаюсь, но разве помощники не только для взглядов? Обычно, если вам нужна функция в контроллере, вы помещаете ее в ApplicationController, поскольку каждая функция доступна в его дочерних классах.

6 голосов
/ 23 января 2012

Как сказал gamecreature в этот пост :

  • В Rails 2 используется переменная @template.
  • В Rails 3 используется метод контроллера view_context
4 голосов
/ 21 сентября 2011

помощники предназначены для представлений, но добавление строки кода для включения этого вспомогательного файла в ApplicationController.rb может решить вашу проблему. в вашем случае вставьте следующую строку в ApplicationController.rb:

include ApplicationHelper
3 голосов
/ 01 июля 2014

Попробуйте добавить module_function(*instance_methods) в свои вспомогательные модули, после чего вы можете напрямую вызывать эти методы для самого модуля.

3 голосов
/ 05 марта 2010

Насколько я знаю, helper :all делает помощников доступными в представлениях ...

1 голос
/ 24 марта 2017

хотя не рекомендуется вызывать помощников в контроллере, поскольку помощники предназначены для использования в представлениях лучший способ использовать помощники в контроллере - это создать вспомогательный метод в application_controller и вызвать их для контроллера,
но даже если требуется вызвать помощника в контроллере
тогда просто включите помощника в контроллере

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

и вызовите вспомогательные методы непосредственно к контроллеру

 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

Контроллер

class ControllerName < ApplicationController
include OffersHelper

def new
  generate_qr_code('Example Text')
end
end

надеюсь, это поможет!

0 голосов
/ 18 мая 2015

Попробуйте, чтобы получить доступ к вспомогательной функции непосредственно с ваших контроллеров view_context.helper_name

...