rails: методы из модуля, включенного в контроллер, недоступны для просмотра

Странная вещь — у меня есть модуль аутентификации в lib/ вот так:

module Authentication
  protected

  def current_user
    User.find(1)
  end

end

а в ApplicationController я включаю этот модуль и все хелперы, но метод current_user доступен в контроллерах, но не из представлений :( Как мне заставить это работать?


person Alexey Poimtsev    schedule 12.08.2009    source источник
comment
UPD: версия рельсов 2.3.3   -  person Alexey Poimtsev    schedule 12.08.2009
comment
Ах да, наконец, звучит так, как будто вам было бы выгодно создать это как плагин вместо отдельного файла в /lib.   -  person kch    schedule 12.08.2009
comment
Какой смысл в return unless m < ActionController::Base?   -  person Liquiddots    schedule 17.11.2010


Ответы (2)


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

class ApplicationController < ActionController::Base

  def current_user
    # ...
  end

  helper_method :current_user
end

С модулем вы можете сделать то же самое, но это немного сложнее.

module Authentication
  def current_user
    # ...
  end

  def self.included m
    return unless m < ActionController::Base
    m.helper_method :current_user # , :any_other_helper_methods
  end
end

class ApplicationController < ActionController::Base
  include Authentication
end

Ах, да, если ваш модуль должен быть строго вспомогательным модулем, вы можете сделать, как сказал Лихтамберг. Но опять же, вы можете просто назвать его AuthenticationHelper и поместить в папку app/helpers.

Хотя, судя по моему собственному опыту работы с кодом аутентификации, вы будете иметь доступ к нему как для контроллера, так и для представлений. Потому что обычно вы будете обрабатывать авторизацию в контроллере. Помощники доступны исключительно для представления. (Я полагаю, что они изначально предназначались для сокращения сложных HTML-конструкций.)

person kch    schedule 12.08.2009
comment
у меня есть неопределенный метод `helper_method' для #‹Class:0xb139e5c› на m.helper_method:current_user :((( - person Alexey Poimtsev; 12.08.2009
comment
Это странно. Я протестировал код выше. Вы должны включить аутентификацию во что-то кроме контроллеров. В этом случае просто добавьте к этой строке условие: if m ‹ ActionController::Base - person kch; 12.08.2009
comment
Я обновил пример, чтобы обработать ситуацию, когда модуль включен в вещи, которые не являются контроллерами. - person kch; 12.08.2009
comment
Та же проблема, что и у Алексея Поимцева, может быть, этот пример устарел для рельсов 3? - person Brian Armstrong; 20.01.2012
comment
helper_method было то, что я искал. Я часто использую current_business в своих контроллерах и представлениях, поэтому имеет смысл просто добавить контроллер и сделать его доступным в представлениях. - person gabe; 25.03.2015
comment
Как вы тестируете helper_method? - person James Klein; 10.06.2016

Вы объявили это с помощью

  helper :foo             # => requires 'foo_helper' and includes FooHelper
  helper 'resources/foo'  # => requires 'resources/foo_helper' and includes Resources::FooHelper

в вашем ApplicationController?

http://railsapi.com/doc/rails-v2.3.3.1/classes/ActionController/Helpers/ClassMethods.html#M001904

person BvuRVKyUVlViVIc7    schedule 12.08.2009
comment
у меня уже есть помощник контроллера приложения: разве этого недостаточно? - person Alexey Poimtsev; 12.08.2009
comment
helper :all будет загружать хелперы только в папку app/helpers (и в плагины движка), и я думаю, только если они названы something_helper.rb / SomethingHelper. - person kch; 12.08.2009
comment
Ну, тогда вам придется делать что-то еще немного вручную. Смотрите мой ответ выше. - person kch; 12.08.2009