Мое приложение должно представить HTML, для ответа, когда пользователь нажимает ajax-ссылку.
Мой контроллер:
def create_user
@user = User.new(params)
if @user.save
status = 'success'
link = link_to_profile(@user) #it's my custom helper in Application_Helper.rb
else
status = 'error'
link = nil
end
render :json => {:status => status, :link => link}
end
Мой помощник:
def link_to_profile(user)
link = link_to(user.login, {:controller => "users", :action => "profile", :id => user.login}, :class => "profile-link")
return(image_tag("/images/users/profile.png") + " " + link)
end
Я попробовал такие методы:
ApplicationController.helpers.link_to_profile(@user)
# It raises: NoMethodError (undefined method `url_for' for nil:NilClass)
и:
class Helper
include Singleton
include ActionView::Helpers::TextHelper
include ActionView::Helpers::UrlHelper
include ApplicationHelper
end
def help
Helper.instance
end
help.link_to_profile(@user)
# It also raises: NoMethodError (undefined method `url_for' for nil:NilClass)
Кроме того, да, я ЗНАЮ о: helper_method, и это работает, но я не хочу перегружать свой ApplicationController с большим количеством этого методы
Оки. Подведем итоги. Вам нужен доступ к определенным функциям / методам, но вы не хотите, чтобы эти методы были привязаны к текущему объекту.
Итак, вы хотите создать прокси-объект, который будет прокси / делегировать эти методы.
class Helper
class << self
#include Singleton - no need to do this, class objects are singletons
include ApplicationHelper
include ActionView::Helpers::TextHelper
include ActionView::Helpers::UrlHelper
include ApplicationHelper
end
end
И в контроллере:
class UserController < ApplicationController
def your_method
Helper.link_to_profile
end
end
Основным недостатком этого подхода является то, что из вспомогательных функций у вас не будет доступа к контексту контроллера (например, у вас не будет доступа к параметрам, сеансу и т. Д.)
Компромиссом было бы объявление этих функций частными во вспомогательном модуле, поэтому, когда вы включите модуль, они также будут частными в классе контроллера.
module ApplicationHelper
private
def link_to_profile
end
end
class UserController < ApplicationController
include ApplicationHelper
end
, как указал Дэмиен .
Обновление : Причина, по которой вы получаете ошибку «url_for», заключается в том, что у вас нет доступа к контексту контроллера, как указано выше. Вы можете принудительно передать контроллер в качестве параметра (в стиле Java;)), например:
Helper.link_to_profile(user, :controller => self)
, а затем в вашем помощнике:
def link_to_profile(user, options)
options[:controller].url_for(...)
end
или в случае более серьезного взлома, представленного здесь . Тем не менее, я бы рекомендовал решение с закрытыми методами и включением их в контроллер.
помощники - это просто рубиновые модули, которые вы можете включать в любой контроллер, как и любой другой. модуль.
module UserHelper
def link_to_profile(user)
link = link_to(user.login, {:controller => "users", :action => "profile", :id => user.login}, :class => "profile-link")
return(image_tag("/images/users/profile.png") + " " + link)
end
end
И в вашем контроллере:
class UserController < ApplicationController
include UserHelper
def create
redirect_to link_to_profile(User.first)
end
end
Получи! http://apotomo.de/2010/04/activehelper-rails-is-no-pain-in-the-ass/
Это именно то, что ты искал, чувак.