如何使rails帮助程序更加面向对象

时间:2009-05-12 02:50:39

标签: ruby-on-rails oop helpers

对于所有帮助者,我希望在整个Rails应用程序中替换以下语法:

time_ago_in_words(@from_time)

用这个:

@from_time.time_ago_in_words

理想情况下,此更改还可以在我的应用程序中的任何位置提供帮助程序(例如,5.times也是如此)。

有没有人知道这样做的插件?我自己卷起来难吗?

4 个答案:

答案 0 :(得分:4)

如果您创建新模型,则可以使其从现有类继承方法。

示例(app / models / mykindofstring.rb):

class Mykindofstring < String

    def all_caps_and_reverse
        self.upcase.reverse
    end 

end

然后从控制器:

@my_string = Mykindofstring.new('This is my string')

最后从视图中调用它:

<%= @my_string %>

显示为这是我的字符串,而:

<%= @my_string.all_caps_and_reverse %>

显示为GNIRTS YM SI SIHT。

该类继承自字符串类,因此应用于字符串的所有方法也适用于mykindofstring对象。它中的方法只是两个现有字符串方法组合的新名称,但您可以使它做任何您想做的事情,例如将时间转换为格式化字符串的方法。

基本上它只是使用您自己的方法扩展当前的Ruby类,而不是使用函数/帮助器。

主要编辑

基于Ians对此答案的评论以及他自己对上述问题的回答,我在Rails中玩了一下,然后将其添加到application_helper.rb中:

module ApplicationHelper
  String.class_eval do
    def all_caps_and_reverse
      self.upcase.reverse
    end
  end
end

现在只需在app中的任何字符串上调用该方法:

@string = 'This is a string.'
@string.all_caps_and_reverse

.nirts a si sihT

答案 1 :(得分:1)

对于所有(甚至大多数)帮助者,您在整个应用程序中找不到任何简单的方法。

Helpers的结构是要包含在视图渲染类中的模块。要利用它们,你必须保留一个ActionView的副本(我认为这不是一个巨大的交易)。

您可以随时打开课程并指定所需的每个助手:

class Time
  def time_ago_in_words
    ActionView::Base.new.time_ago_in_words self
  end
end

>> t = Time.now
=> Tue May 12 10:54:07 -0400 2009
>> t.time_ago_in_words
=> "less than a minute"
(wait a minute)
>> t.time_ago_in_words
=> "1 minute"

如果采用这种方法,我建议缓存您使用的ActionView :: Base实例。或者,如果你不想如此重量级,你可以创建自己的类来包含你想要的帮助程序(你不希望直接在每个时间,日期,字符串等类中包含帮助程序,尽管,因为这会使方法命名空间变得非常激烈 - 并且与你想要的自然名称冲突。)

答案 2 :(得分:1)

如果您使用的是Ruby 2.1,则可以使用优化。它们是猴子修补Ruby类的替代品。借用@Jarrod's monkey-patch例子:

module MyString
  refine String do
    def all_caps_and_reverse
      upcase.reverse
    end
  end
end

您现在可以在任何想要的对象中使用它:

class Post
  using MyString
end
@post.title.all_caps_and_reverse

你可以read more about Refinements在这里。

答案 3 :(得分:0)

制作模型,TimeAgo或类似的东西。在这里实现以下这个想法: a code snippet for "wordifying" numbers

然后,在您的控制器中,使用此类创建实例变量。然后,在您的视图中,请致电@from_time.in_words