我的帮助方法在控制器 [英] My helper methods in controller

查看:142
本文介绍了我的帮助方法在控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我的控制器:



我的应用程序应该呈现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)
#引发:NoMethodError(undefined method`url_for'for nil:NilClass)
/ pre>

和:

  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.

这篇关于我的帮助方法在控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆