【问题标题】:Should I use the `lib` folder or the `initializers` folder for Rails monkey patches?我应该为 Rails 猴子补丁使用 `lib` 文件夹还是 `initializers` 文件夹?
【发布时间】:2014-12-21 09:41:49
【问题描述】:

我有一些函数可以在一个名为string_class.rb 的文件中对字符串类进行猴子修补,该文件当前位于config\initializers\string_class.rb 中。代码如下所示:

class String

  def capitalize_first_char
    self.sub(/^(.)/) { $1.capitalize }
  end

  def capitalize_each_sentence
    self.gsub(/([a-z])((?:[^.?!]|\.(?=[a-z]))*)/i) { $1.upcase + $2.rstrip }
  end

end

在做了相当多的研究之后,我不确定这个类是否应该放在 initializerslib 文件夹中。

【问题讨论】:

  • 顺便说一句,这些是修补字符串的不良候选者。它们(大概)纯粹是为了展示目的。您应该只在app/helpers/*_helper.rb 中编写辅助函数。
  • @meagar 我希望它们在所有控制器和视图中都可用,所以助手会出来吗?
  • 不,这对助手来说是很正常的要求。如果您的控制器需要它们,您只需在ApplicationController 中定义方法。这使得它们对所有控制器都可用,而不是从您的 ApplicationController 继承,这应该是所有控制器。然后用helper_method :capitalize_first_char, :capitalize_each_sentence 指定它们是辅助方法,它们也将在每个视图中可用。
  • @meagar 我更喜欢这个主意,我会把它们移到那里。如果您想在下面添加答案,我会折腾您:)
  • 在核心课程中胡闹几乎总是一个坏主意。字符串就是字符串,每个 Ruby 开发人员都希望它们以某种方式运行。将新方法修补到字符串中意味着 your 字符串的行为与其他字符串略有不同。这也意味着,如果新版本的 Ruby 引入同名的方法(不太可能,不可否认),您的代码将突然隐藏一个真正的 String 方法。在实践中,当有真正的需要时,可以extreme适度地修补核心类。这不是其中一种情况。

标签: ruby-on-rails ruby directory monkeypatching


【解决方案1】:

这种事情在 Rails 应用程序中没有一个好地方,因为这不是您在构建 Rails 应用程序的正常过程中应该做的事情。在几乎所有样式指南中,修补核心类都是expressly advised against

  • config/initializers 可能是错误的地方。通常这是为您的应用设置依赖项,大多数人不会想到在那里寻找将奇怪方法混合到核心类中的代码
  • lib 可能是一个更好的地方,但默认情况下它不会自动重新加载
  • Gemfile?如果这值得修补到 String 中,那么它可能值得提炼成 Gem 并彻底记录。

我个人会回避这个问题并简单地介绍辅助方法。您可以通过在app/controllers/application_controller.rb 中定义这些辅助方法,使它们在所有控制器中可用。然后,您可以使用 helper_method 函数使这些方法可用于您的视图:

class ApplicationController < ActionController::Base

  helper_method :capitalize_first_char, :capitalize_each_sentence

  #...

  protected

  def capitalize_first_char(str)
    str.sub(/^(.)/) { $1.capitalize }
  end

  def capitalize_each_sentence(str)
    str.gsub(/([a-z])((?:[^.?!]|\.(?=[a-z]))*)/i) { $1.upcase + $2.rstrip }
  end
end

【讨论】:

  • 我喜欢这里的发展方向,但还有最后一个问题。这些助手是属于应用程序控制器还是属于应用程序助手?
  • @meager 我得到了它的工作,我有一个糟糕的复制和粘贴。感谢您对此的帮助。
  • @chrishough ApplicationHelper 方法在控制器中不可用,它们仅用于视图。如果您在控制器和视图中都需要它们,它们应该进入控制器并通过helper_method 提供给视图。
猜你喜欢
  • 2010-09-29
  • 2011-01-14
  • 1970-01-01
  • 2018-12-12
  • 1970-01-01
  • 2021-07-16
  • 2011-09-08
  • 2013-04-08
  • 2011-03-26
相关资源
最近更新 更多