Ruby-on-rails 我在控制器中的辅助方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2590912/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 22:30:33  来源:igfitidea点击:

My helper methods in controller

ruby-on-railscontrollerhelper

提问by VizakenHyman

My app should render html, to answer when a user clicks ajax-link.

我的应用程序应该呈现 html,以便在用户单击 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

此外,是的,我知道 :helper_method,它可以工作,但我不想用大量这样的方法重载我的 ApplicationController

回答by Damien MATHIEU

helpers are just ruby modules which you can include in any controller just like any module.

助手只是 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

And, in your controller :

而且,在您的控制器中:

class UserController < ApplicationController
    include UserHelper

    def create
        redirect_to link_to_profile(User.first)
    end
end

回答by Vlad Zloteanu

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.

一个折衷方案是在 helper 模块中将这些函数声明为私有,因此,当您将包含该模块时,它们在控制器类中也将是私有的。

module ApplicationHelper
  private
  def link_to_profile
  end
end

class UserController < ApplicationController
  include ApplicationHelper
end

, as Damienpointed 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:

更新:您收到 'url_for' 错误的原因是您无权访问控制器的上下文,如上所述。您可以强制将控制器作为参数(Java 样式 ;) )传递,例如:

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.

或事件更大的黑客,呈现在这里。但是,我会推荐将方法设为私有并将它们包含在控制器中的解决方案。

回答by Nick

Take that! http://apotomo.de/2010/04/activehelper-rails-is-no-pain-in-the-ass/

拿着它!http://apotomo.de/2010/04/activehelper-rails-is-no-pain-in-the-ass/

That's exactly what you were looking for, dude.

这正是你要找的,伙计。