Rails-如何在控制器内部使用助手


207

虽然我意识到您应该在视图内使用一个帮助器,但是在构建JSON对象以返回时,我的控制器中需要一个帮助器。

它有点像这样:

def xxxxx

   @comments = Array.new

   @c_comments.each do |comment|
   @comments << {
     :id => comment.id,
     :content => html_format(comment.content)
   }
   end

   render :json => @comments
end

如何获得我的html_format助手?


2
您可能需要考虑@grosser的答案,它的答案要完整得多。
托克兰,

我知道这很老了,但是...红宝石类怎么了?:p
Tarek 2015年

Answers:


205

注意:这是在Rails 2天之内编写并接受的;如今,格罗斯的答案是要走的路。

选项1:可能最简单的方法是在控制器中包含辅助模块:

class MyController < ApplicationController
  include MyHelper

  def xxxx
    @comments = []
    Comment.find_each do |comment|
      @comments << {:id => comment.id, :html => html_format(comment.content)}
    end
  end
end

选项2:或者,您可以将helper方法声明为类函数,并按如下方式使用它:

MyHelper.html_format(comment.content)

如果希望既可以将其用作实例函数又可以用作类函数,则可以在助手中声明两个版本:

module MyHelper
  def self.html_format(str)
    process(str)
  end

  def html_format(str)
    MyHelper.html_format(str)
  end
end

希望这可以帮助!


谢谢,但我有点困惑。现在,我的助手在/app/helpers/application_helper.rb中。您是否建议我将助手移动到ApplicationController?
2011年

我在我的application_controller中添加了“ include ApplicationHelper”,但是出现了“ NoMethodError”错误(ApplicationHelper:Module的未定义方法“ html_format”):”
AnApprentice,2011年

1
@AnApprentice看起来您已经明白了,但是我稍微调整了一下答案,希望可以使情况变得更清楚。在第一个版本中,您只能使用html_format-仅MyHelper.html_format在第二个版本中需要。
泽维尔·霍尔特

4
当您要使用的辅助方法使用诸如的视图方法时,此方法将不起作用link_to。控制器无权使用这些方法,我的大多数助手都使用这些方法。另外,将帮助程序包含在控制器中会将所有帮助程序的方法公开为可公开访问的操作,这是不好的。view_context是在Rails 3中走的路
。– GregT

@GregT-之前没有看到格罗斯的答案,因为它是在事实发生之后出现的,但是我也更喜欢它。他刚得到我的支持。
Xavier Holt 2013年

304

您可以使用

  • helpers.<helper>Rails 5+(或ActionController::Base.helpers.<helper>)中
  • view_context.<helper>Rails 4和3)(警告:这会为每个调用实例化一个新的视图实例)
  • @template.<helper>滑轨2
  • 在单例课程中包括帮助者,然后 singleton.helper
  • include 控制器中的帮助程序(警告:会将所有帮助程序方法变为控制器操作)

56
这个答案更好!在rails 3中,简单的调用view_context.helper_function很简单并且效果很好。ActionController::Base.helpers.helper_function同样好。
trisweb 2012年

29
view_context=天才
n_i_c_k

5
警告:请勿使用view_context。它将在每次调用时实例化一个新的视图实例...
fny 2015年

7
ActionController::Base.helpers.helper_function似乎不起作用。我NoMethodError - undefined method spell_date_and_time' for #<ActionView::Base:0x007fede56102d0>:在尝试调用ActionController::Base.helpers.spell_date_and_time()控制器方法时得到提示。调用view_context.spell_date_and_time()确实可以。
fish鱼

37
轨道5:简单地使用helpers.helper_function在你的控制器(github.com/rails/rails/pull/24866
马库斯

80

在Rails 5中,使用helpers.helper_function控制器中的。

例:

def update
  # ...
  redirect_to root_url, notice: "Updated #{helpers.pluralize(count, 'record')}"
end

资料来源:来自@Markus关于不同答案的评论。我觉得他的答案应该是自己的答案,因为这是最干净,更轻松的解决方案。

参考:https : //github.com/rails/rails/pull/24866


6
感觉有点奇怪,在控制台中您会helper以单数形式调用,而在控制器中则是复数形式。
陌生人研究员

10

使用选项1解决了我的问题。最简单的方法可能是在控制器中包含辅助模块:

class ApplicationController < ActionController::Base
  include ApplicationHelper

...

1
唯一的缺点是它添加了带有辅助功能名称的控制器动作。但是,我也这样做:)
Felix

9

通常,如果要在(仅)控制器中使用辅助程序,我更喜欢将其声明为的实例方法class ApplicationController


5
作为一种受保护的方法
本杰明·克鲁兹耶

3

在Rails 5+中,您可以简单地使用以下示例中演示的功能:

module ApplicationHelper
  # format datetime in the format #2018-12-01 12:12 PM
  def datetime_format(datetime = nil)
    if datetime
      datetime.strftime('%Y-%m-%d %H:%M %p')
    else
      'NA'
    end
  end
end

class ExamplesController < ApplicationController
  def index
    current_datetime = helpers.datetime_format DateTime.now
    raise current_datetime.inspect
  end
end

输出值

"2018-12-10 01:01 AM"

0
class MyController < ApplicationController
    # include your helper
    include MyHelper
    # or Rails helper
    include ActionView::Helpers::NumberHelper

    def my_action
      price = number_to_currency(10000)
    end
end

在Rails 5+中,只需使用助手helpers.number_to_currency(10000)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.