Подтвердить что ты не робот

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

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

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
4b9b3361

Ответ 1

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

EDIT: чтобы быть ясным, я думаю, что большая путаница (исправить меня, если я ошибаюсь) связана с вызовом helper :all. helper :all действительно включает в себя все ваши помощники для использования под любым контроллером на стороне просмотра. В гораздо более ранних версиях Rails пространство имен помощников определяло, какие представления контроллеров могут использовать помощники.

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

Ответ 2

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

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

  • использовать view_context
  • определить его в контроллере и сделать доступным с помощью метода класса helper_method http://apidock.com/rails/ActionController/Helpers/ClassMethods/helper_method
  • определить его в совместно используемом модуле и включить/расширить

Ответ 3

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

class ApplicationController < ActionController::Base
  protect_from_forgery       
  include ApplicationHelper  
end

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

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

Ответ 4

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

Ответ 5

Как сказано gamecreature в этом сообщении:

  • В Rails 2 используйте переменную @template.
  • В Rails 3 используйте метод контроллера view_context

Ответ 6

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

include ApplicationHelper

Ответ 7

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

Ответ 8

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

Ответ 9

У меня была та же проблема...

вы можете взломать/обмануть его, поместить эту логику в модель или создать класс специально для этого. Модели доступны для контроллеров, в отличие от этих призрачных вспомогательных методов.

Вот моя модель "rag.rb"

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

Вот часть моего контроллера "rags_controller.rb"

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

Это вызвало катапульту на терминале после того, как я нажал кнопку "Обновить".

При создании экземпляра можно вызвать методы в модели. Замените catattack на некоторые коды. (Это лучшее, что у меня есть до сих пор)

: helper all открывает только помощники до представлений.

Это показывает, как создать класс и вызвать его. http://railscasts.com/episodes/101-refactoring-out-helper-object?autoplay=true

Ответ 10

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

Ответ 11

хотя это не очень хорошая практика для вызова помощников в контроллере, поскольку помощники предназначены для использования в представлениях лучший способ использовать помощников в контроллере - создать вспомогательный метод в 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

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