我在控制器中的辅助方法 [英] My helper methods in controller
问题描述
我的应用程序应该呈现 html,以便在用户单击 ajax-link 时进行响应.
My app should render html, to answer when a user clicks 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
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.让我们回顾一下.您想要访问某些功能/方法,但您不希望这些方法附加到当前对象.
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
并且,在控制器中:
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
,正如 Damien 指出的那样.
, as Damien pointed out.
更新:您收到url_for"错误的原因是您无权访问控制器的上下文,如上所述.您可以强制将控制器作为参数(Java 样式 ;) )传递,例如:
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)
然后,在你的助手中:
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.
这篇关于我在控制器中的辅助方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!