问题描述
我的控制器:
我的应用程序应该呈现html,以便在用户单击ajax链接时回答。 pre> def create_user
@user = User.new(params)
如果@ user.save
status ='success'
link = link_to_profile(@user)#它是我在Application_Helper.rb中的自定义助手
else
status ='error'
link = nil
end
render: json => {:status => status,:link => link}
end
我的帮助:
$ b b
def link_to_profile(user)
link = link_to(user.login,{:controller =>users,:action = id => user.login},:class =>profile-link)
return(image_tag(/ images / users / profile.png)++ link)
end
我尝试过这样的方法:
ApplicationController.helpers.link_to_profile(@user)
/ pre>
#引发:NoMethodError(undefined method`url_for'for nil:NilClass)
和:
class Helper
Singleton
包括ActionView :: Helpers :: TextHelper
include ActionView :: Helpers :: UrlHelper
include ApplicationHelper
end
def help
Helper.instance
end
help.link_to_profile(@user)
#它还引发:NoMethodError(未定义方法`url_for'for nil:NilClass)
此外,是的,我知道:helper_method,它的工作原理,但我不想重载我的ApplicationController与大量的方法
解决方案Oki。让我们回顾一下。您希望访问certaint函数/方法,但不希望将这些方法附加到当前对象。
所以你想创建一个代理对象,代理/委托这些方法。
class Helper
class<< self
#include Singleton - 无需这样做,类对象是单例
include ApplicationHelper
include ActionView :: Helpers :: TextHelper
include ActionView :: Helpers :: UrlHelper
include ApplicationHelper
end
end
/ p>
class UserController< ApplicationController
def your_method
Helper.link_to_profile
end
end
这种方法的主要缺点是从帮助函数,您将无法访问控制器上下文(EG您将无法访问params,会话等)
一个妥协就是在helper模块中声明这些函数是私有的,因此,当你包含这个模块时,它们在控制器类中也是私有的。
模块ApplicationHelper
private
def link_to_profile
end
end
class UserController< ApplicationController
包括ApplicationHelper
end
,作为指出。
更新:你得到'url_for'错误的原因是你没有访问控制器的上下文,如上所述。你可以强制传递控制器作为一个参数(Java风格;))如:
Helper.link_to_profile => self)
,然后在您的助手中:
def link_to_profile(user,options)
options [:controller] .url_for(...)
end
或事件更大的黑客,提出。但是,我会建议解决方案使方法私有和包括他们在控制器。
My app should render html, to answer when a user clicks ajax-link.
My controller:
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
My helper:
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
I have tried such methods:
ApplicationController.helpers.link_to_profile(@user) # It raises: NoMethodError (undefined method `url_for' for nil:NilClass)
and:
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)
In addition, yes, I KNOW about :helper_method, and it works, but i don't want to overload my ApplicationController with a plenty of that methods
解决方案Oki. Let's recap. You want access to certaint functions/methods, but you don't want those methods to be attached to current object.
So you want to make a proxy object, that will proxy/delegate to those methods.
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
And, in controller:
class UserController < ApplicationController def your_method Helper.link_to_profile end end
The main disadvantage to this approach is that from the helper functions you won't have access to controller context (EG you won't have access to params, session, etc)
A compromise would be to declare those functions as private in the helper module, therefore, when you will include the module, they will also be private in the controller class.
module ApplicationHelper private def link_to_profile end end class UserController < ApplicationController include ApplicationHelper end
, as Damien pointed out.
Update: The reason why you get the 'url_for' error is that you do not have access to controller's context, as stated above. You could force passing the controller as a parameter(Java-style ;) ) like:
Helper.link_to_profile(user, :controller => self)
and then, in your helper:
def link_to_profile(user, options) options[:controller].url_for(...) end
or event a bigger hack, presented here. However, i would reccomend the solution with making methods private and including them in the controller.
这篇关于我的帮助方法在控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!