0

我有一个ActiveRecord find带有一些业务逻辑的猴子补丁,例如:

# 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应该在文件夹app/core_extensions/ 中,不是吗?


编辑,在塞尔吉奥回答之后

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

# 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
4

2 回答 2

2

这是我第一次看到这种情况:)。我将其放入app/core_extensions并检查实时重新加载是否可以正常工作。如果没有,我会把它移到lib/. (这只是一个启发式)

编辑:

而不是扩展NilClass我宁愿使用常规的 NullObjects。它真的不那么令人惊讶并且更容易理解。

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

于 2018-11-30T14:04:25.383 回答
2

finder.rb 应该在哪里?

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

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

当用户查找 Family 时Family.find(params[family_id],session[:company_id]),此查找会将家庭结果 family.company 的公司与参数进行比较

为什么不做这样的事情:

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

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

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

相同的效果*,只是没有任何补丁。更具前瞻性。您甚至可以添加一些 rubocop 规则,以确保您永远不会编写裸Family.find.


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

于 2018-11-30T14:21:52.260 回答