繁体   English   中英

如何使Rails助手更加面向对象

[英]How can I make rails helpers more object-oriented

对于所有助手,我想在整个Rails应用程序中替换以下语法:

time_ago_in_words(@from_time)

有了这个:

@from_time.time_ago_in_words

理想情况下,此更改还将使助手在我的应用程序中的任何位置都可用(以相同的方式,例如5.times )。

有人知道这样做的插件吗? 自己滚会很难吗?

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

示例(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

现在,只需在应用程序中的任何字符串上调用该方法:

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

.gnirts一个sihT

如果您使用的是Ruby 2.1,则可以使用优化。 它们是猴子修补Ruby类的替代方法。 借用@Jarrod的猴子补丁示例:

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

您可以在此处阅读有关优化的更多信息

对于所有(甚至大多数)助手,您都找不到在整个应用程序中执行此操作的简便方法。

帮助器被构造为旨在包含在视图呈现类中的模块。 要利用它们,您必须保留一个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实例。 或者,如果您不想这么繁重,则可以创建自己的类以仅包含所需的帮助器(尽管您不想直接在每个Time,Date,String等类中包含这些帮助器,但是,因为这会使方法名称空间变得非常混乱-并与您想要的自然名称冲突)。

制作模型,TimeAgo或类似的东西。 在这里实现以下想法: 用于“数字化”数字的代码段

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM