Ruby on rails 如何使rails助手更面向对象

Ruby on rails 如何使rails助手更面向对象,ruby-on-rails,oop,helpers,Ruby On Rails,Oop,Helpers,对于我整个Rails应用程序中的所有助手,我希望替换以下语法: time_ago_in_words(@from_time) 为此: @from_time.time_ago_in_words 理想情况下,此更改还将使助手在我的应用程序中的任何位置都可用(相同的方式,例如,5.timesis) 有人知道这样做的插件吗?我自己做会很困难吗?制作一个模型,很久以前或者类似的东西。在这里实现以下想法: 然后,在控制器中,使用该类创建实例变量。然后,在你看来,从_time调用。_words制作一个模型

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

time_ago_in_words(@from_time)
为此:

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


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

制作一个模型,很久以前或者类似的东西。在这里实现以下想法:


然后,在控制器中,使用该类创建实例变量。然后,在你看来,从_time调用
。_words

制作一个模型,TimeAgo或类似的东西。在这里实现以下想法:


然后,在控制器中,使用该类创建实例变量。然后,在您的视图中,从\u time调用
。\u换句话说

如果您创建了一个新模型,您可以让它从现有类继承方法

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

最后从视图中调用它:

<%= @my_string %>
现在只需在应用程序中的任何字符串上调用该方法:

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

.gnirts一个si-sihT

如果您创建了一个新模型,您可以使它继承现有类中的方法

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

最后从视图中调用它:

<%= @my_string %>
现在只需在应用程序中的任何字符串上调用该方法:

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

.gnits a si sihT

对于所有(甚至大多数)助手,在整个应用程序中都找不到任何简单的方法来完成此操作

辅助对象被构造为要包含在视图渲染类中的模块。要利用它们,您必须保留一份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实例。或者,如果您不想变得如此重量级,您可以创建自己的类来只包含您想要的帮助程序(但是,您不想在每个时间、日期、字符串等类中直接包含帮助程序,因为这会非常严重地扰乱方法命名空间,并与您想要的自然名称冲突).

对于所有(甚至大多数)助手来说,在整个应用程序中都找不到任何简单的方法来实现这一点

辅助对象被构造为要包含在视图渲染类中的模块。要利用它们,您必须保留一份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实例。或者,如果您不想变得如此重量级,您可以创建自己的类来只包含您想要的帮助程序(但是,您不想在每个时间、日期、字符串等类中直接包含帮助程序,因为这会非常严重地扰乱方法命名空间,并与您想要的自然名称冲突).

如果您使用的是Ruby 2.1,那么您可以使用改进。它们是猴子修补Ruby类的替代品。举个例子:

现在,您可以在任何想要的对象中使用此选项:

class Post
  using MyString
end
@post.title.all_caps_and_reverse

您可以在这里使用。

如果您使用的是Ruby 2.1,那么您可以使用改进。它们是猴子修补Ruby类的替代品。举个例子:

现在,您可以在任何想要的对象中使用此选项:

class Post
  using MyString
end
@post.title.all_caps_and_reverse

您可以在这里查看。

为什么这很重要?也许一些上下文会有所帮助……我只是觉得它们现有的语法既烦人又难看。在我的模型中调用@post.truncate这样的东西也很好(例如用于缓存)。为什么这很重要?也许一些上下文会有所帮助……我只是觉得它们现有的语法既烦人又难看。在我的模型中调用@post.truncate这样的东西(比如缓存)也很好,但它是Ruby!子类化是“适当的”OO,但您不想创建另一种类型的新对象,您想使用实际的上帝赋予的字符串,所以只需打开String类并添加您的方法:class String;def所有_caps_和_reverse;self.upcase.reverse;结束;谢谢,说得好。我相应地修改了答案。顺便说一句,这就是为什么我喜欢堆栈溢出;我在这里只呆了几天,我的代码已经在改进。为什么要用class_eval而不仅仅是重新定义string类呢?在ApplicationHelper模块中,class_eval可以工作。在外部时,重新打开该类是有效的(我只是在同一个文件中,在ApplicationHelper下面这样做)。这可能与在模块内定义类有关。在进行一些尝试和错误处理时,我不得不重新启动应用程序,因此它可能也与Rails如何自动加载有关。我确信还有其他地方可以使用它,也有其他方法可以使用它,但是为了快速添加到类中,在Rails加载路径中已经存在的东西中使用class_eval似乎是更好的做法。但是它是Ruby!子类化是“适当的”OO,但您不想创建另一种类型的新对象,您想使用实际的上帝赋予的字符串,所以只需打开String类并添加您的方法:class String;def所有_caps_和_reverse;self.upcase.reverse;结束;谢谢,说得好。我相应地修改了答案。顺便说一句,这就是为什么我喜欢堆栈溢出;我在这里只呆了几天,我的代码已经在改进。为什么要用class_eval而不仅仅是重新定义string类呢?在ApplicationHelper模块中,class_eval可以工作。在外部时,重新打开该类是有效的(我只是在同一个文件中,在ApplicationHelper下面这样做)。这可能与在模块内定义类有关。在进行一些尝试和错误处理时,我不得不重新启动应用程序,因此它可能也与Rails如何自动加载有关。我相信还有其他地方可以使用它,也有其他方法可以使用它,但是为了快速添加到类中,在Rails加载路径中已经存在的东西中使用class_eval似乎是更好的实践。
class Post
  using MyString
end
@post.title.all_caps_and_reverse