我的应用应呈现html,以便在用户点击ajax-link时回答。
我的控制器:
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
答案 0 :(得分:15)
帮助程序只是ruby模块,您可以像任何模块一样包含在任何控制器中。
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
答案 1 :(得分:13)
冲。让我们回顾一下。您希望访问某些功能/方法,但您不希望将这些方法附加到当前对象。
因此,您希望创建一个代理对象,代理/委托这些方法。
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
这种方法的主要缺点是,从辅助函数中你将无法访问控制器上下文(EG将无法访问参数,会话等)
折衷方案是在辅助模块中将这些函数声明为私有,因此,当您包含模块时,它们在控制器类中也将是私有的。
module ApplicationHelper
private
def link_to_profile
end
end
class UserController < ApplicationController
include ApplicationHelper
end
,正如Damien指出的那样。
更新:您收到'url_for'错误的原因是您无法访问控制器的上下文,如上所述。您可以强制将控制器作为参数(Java样式;))传递,如:
Helper.link_to_profile(user, :controller => self)
然后,在你的助手中:
def link_to_profile(user, options)
options[:controller].url_for(...)
end
或事件更大的黑客,提出here。但是,我会推荐解决方案,将方法设为私有,并将它们包含在控制器中。
答案 2 :(得分:-1)
拿那个! http://apotomo.de/2010/04/activehelper-rails-is-no-pain-in-the-ass/
这正是你要找的,伙计。