NoMethodError при попытке вызвать вспомогательный метод из контроллера Rails - PullRequest
73 голосов
/ 17 января 2009

Я получаю NoMethodError при попытке доступа к методу, определенному в одном из моих вспомогательных модулей, из одного из моих классов контроллеров. Приложение My Rails использует метод класса helper с символом :all, как показано ниже:

class ApplicationController < ActionController::Base
  helper :all
  .
  .
end

Насколько я понимаю, это должно заставить все мои классы контроллеров автоматически включать все вспомогательные модули в каталог app / helpers, поэтому смешивая все методы с контроллерами. Это правильно?

Если я явно include вспомогательный модуль в контроллере, то все работает правильно.

Ответы [ 13 ]

134 голосов
/ 02 декабря 2010

Чтобы использовать вспомогательные методы, уже включенные в движок шаблонов:

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

Пример использования вызова метода number_to_currency в методе контроллера:

# rails 3 sample
def controller_action
  @price = view_context.number_to_currency( 42.0 ) 
end

# rails 2 sample
def controller_action
  @price = @template.number_to_currency( 42.0 ) 
end
49 голосов
/ 17 января 2009

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

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

30 голосов
/ 20 января 2010

если вам нужно разделить метод между контроллером и помощником / представлением, вы можете просто определить через 'helper_method' в верхней части контроллера:

class ApplicationController < ActionController::Base
  helper_method :my_shared_method
  ...

  def my_shared_method
    #do stuff
  end
end

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

28 голосов
/ 27 января 2009

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

Один из способов получить доступ к вашим вспомогательным методам - ​​просто включить ваш вспомогательный файл.

include LoginHelper
cool_login_helper_method(x,y,z)

Это приводит все методы из этого вспомогательного модуля в область действия вашего контроллера. Это не всегда хорошо. Чтобы отделить область видимости, создайте объект, наделите его полномочиями этого помощника и используйте его для вызова методов:

login_helper = Object.new.extend(LoginHelper)
login_helper.cool_login_helper_method(x,y,z)

Помощник: все

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

7 голосов
/ 10 сентября 2012

Для Rails 3 используйте метод view_context в вашем контроллере:

def foo
  view_context.helper_method
  ...

Вот пример: http://www.christopherirish.com/2011/10/13/no-view_context-in-rails-3-1-changes/

5 голосов
/ 11 июля 2011

Возможно, лучше использовать метод помощников :

class FooController < ActionController::Base
  def action
    self.class.helpers.helper_method arg
  end
end
5 голосов
/ 18 января 2009

Время, когда я нахожу это наиболее необходимым, - это для написания флеш-памяти или пользовательских средств проверки ошибок. При некоторых обстоятельствах приятно использовать такие вещи, как помощники по ссылкам в флеш-сообщении. Я использую следующее решение для добавления помощников ActionView в контроллер. Имейте в виду, что, как упоминалось выше, это нарушает разделение MVC, поэтому, если у кого-то есть идея получше, дайте мне знать!

Ниже ApplicationController добавьте это:

class Something
  include Singleton
  include ActionView::Helpers::UrlHelper
end

и внутри ApplicationController добавьте

def foo
  Something.instance
end

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

messages << "<li class='error'>Your have an Error!<%= foo.link_to('Fix This', some_path) %></li>"

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

4 голосов
/ 06 мая 2010

Доступ к любому помощнику можно получить с помощью переменной @template в контроллере.

@template.my_super_helper

3 голосов
/ 02 марта 2014

Контроллер не может обращаться к вспомогательным методам автоматически. Мы должны включить их в контроллер приложения.

модуль ApplicationHelper

 def hello_message
    "Hello World"
 end

конец

класс ApplicationController

  include ApplicationHelper

  def message
     hello_message
  end

конец

2 голосов
/ 17 января 2009

Помощники должны использоваться с шаблонами, т.е. просмотров, а не в контроллерах. Вот почему вы не можете получить доступ к методу. Если вы хотите разделить метод между двумя контроллерами, вам необходимо определить его, например, в ApplicationController. helper: all говорит, что любой метод, который вы определили в любом файле помощника в каталоге app / helpers, будет доступен для любого шаблона.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...