猴子用 Rails 的业务逻辑修补核心 class

Monkey patching a core class with business logic with Rails

我有一个带有一些业务逻辑的 ActiveRecord find 的 monkeypatched,例如:

# lib/core_extensions/active_record/finder_methods/finder.rb
module ActiveRecord
  module FinderMethods
    def find(*args)
      return super if block_given?  

      #... business logic code =>  my_error_control = true

      raise "My Error" if my_error_control
      retorn = find_with_ids(*args)
    end
  end
end
retorn

这样的例子我没见过多少,这让我产生了疑问:

finder.rb应该在哪里?

在此示例中,此文件位于 lib/core_extensions/... 但如果它包含 业务逻辑 ,我认为 finder.rb 应该位于文件夹 [=18] =] 不是吗?


已编辑,在 Sergio 回答后

这样的事情,是一种不好的做法吗?

# lib/core_extensions/nil_class/image_attributes.rb
# suport for product images attributes
class NilClass
  def main_image(size,evita_video)
    "/images/paperclip_missing/original/missing.png"
  end
end

第一次见到这种情况:)。我会把它放在 app/core_extensions 中并检查实时重新加载是否能正常工作。如果没有,我会把它移到 lib/。 (这只是一种启发式)

编辑:

我宁愿使用常规的 NullObject,而不是扩展 NilClass。真的没那么惊奇,也比较容易理解。

https://robots.thoughtbot.com/rails-refactoring-example-introduce-null-object

Where should finder.rb be?

归根结底,没关系。加载此代码很重要。这种修补基础库和添加业务逻辑的组合看起来像是必须彻底记录的东西(在项目的 wiki 或类似的东西中)。如果它被记录在案,那就没关系了。代码就是文档所说的地方。

不碍事,这里有一个设计建议:

when user seeks a Family Family.find(params[family_id],session[:company_id]), this find will compare the company of the family result family.company witht the parameter

为什么不做这样的事情:

family = current_company.families.find(params[:family_id])

其中 current_company 可以定义为 @current_company ||= Company.find(session[:company_id])

这里,如果这个公司没有这个家庭,你会得到一个例外。

效果相同*,只是没有任何修补。更加面向未来。你甚至可以添加一些 rubocop 规则来确保你永远不会写一个裸体 Family.find


* 这并不是说你添加了那个补丁,你的代码的其余部分就神奇地获得了超能力。不。您仍然需要更改所有查找器,以传递该公司 ID。