【问题标题】:Where to put redefinition classes files, and how to configure them, in a Rails 5 project?在 Rails 5 项目中,在哪里放置重定义类文件,以及如何配置它们?
【发布时间】:2018-11-22 14:45:39
【问题描述】:

重新编辑问题(感谢 Gavin Miller)

如果一个有三种核心扩展(或猴子补丁),像这些例子:

1- 表单构建器

class FormWithBuilder < ActionView::Helpers::FormBuilder
  def object
    # ... my code
  end
end

2-类核心扩展

class Hash
  def translate_values
    th=Hash.new
    self.each{|k,v| th[k]=I18n.translate(v)}
    th
  end
end

3- 表单助手

module ActionView
  module Helpers
    module TranslationHelper

      alias_method :original_localize, :localize
      def localize(*args)
....
      end
     end
  end
end

我必须把这些文件放在哪里?

在 Gavin Miller 回应后,我明白我必须使用正确的文件夹结构,作为 Rails 核心扩展等等。而不是在config/initializers 下使用它们,那是我以前(和工作)的地方。好的,让我们创建文件夹并将它们放在 lib/...

并深深期待我已经意识到使用 config.eager_load_paths 和 config.autoload_paths 是一种不好的做法:

https://edgeguides.rubyonrails.org/autoloading_and_reloading_constants.html#autoload-paths-and-eager-load-paths

https://github.com/rails/rails/issues/13142

并建议将 Gavin Miller 对我说的所有 lib/core_extensions 文件夹放在 app/lib/ 文件夹下,仅此而已,但此解决方案对我不起作用,除非我 require 所有文件,但这就是,据我了解,这不是必需的,因为 app 中的所有内容都是自动加载的。

我想我缺少一些配置

这是在图像中,更容易解释

rails c

Running via Spring preloader in process 9724
Loading development environment (Rails 5.1.5)
2.4.0 :001 > Hash.new.translate_values
NoMethodError: undefined method `translate_values' for {}:Hash

在需要它之后:

2.4.0 :015 > require Rails.root.join('app','lib','core_extensions','hash','localization.rb')
 => true 
2.4.0 :016 > Hash.new.translate_values
 => {} 

谢谢

---- 27/10 编辑

this 是一个糟糕的解决方案吗?只需在config/initilizers/core_extensions.rb

下创建一个文件
Dir.glob(Rails.root.join('lib/core_extensions/**/*.rb')).sort.each do |filename|
  require filename
end

这样我就不需要修改 config.autoload_paths 和 eager_load_paths

【问题讨论】:

  • 你在得到答案一周后是否完全重写了问题?
  • 是的,我无法很好地解释自己,这不是一个可以理解的问题
  • 恢复编辑并提出新的改进问题
  • 好的,我会去做的

标签: ruby-on-rails


【解决方案1】:

您所说的重新定义称为核心扩展(或猴子补丁),并被放入名为 core_extensions 的文件夹中。这样,您就可以将每个功能分解为单独的文件,而不是在单个文件中包含大量不同的功能。 The Rails project illustrates what I mean folder structure wise.

Initializers 是放置它们的一个地方,但我更倾向于遵循 lib/core_extension/class_name/&lt;file_name&gt;.rb 的 Rails 约定,因为它们更容易进行测试,遵循约定,并且如果需要,可以更容易地提取到 gem 中.

查看您的特定文件,我会选择:

- lib
  - core_extensions
    - hash
      - localization.rb
    - action_view
      - helpers
        - translation_helper
          - localization.rb

FormWithBuilder 不是核心扩展,而是子类。 lib 是一个合适的地方,但不要将子类和核心扩展的概念混为一谈,它们是两个非常不同的构造,用于非常不同的目的。

【讨论】:

  • 谢谢,只是一个问题:lib 不会自动加载到 rails 项目中,因此,例如,我必须在我想要的所有文件 (*.html.erb) 中使用 'require core_extensions/action_view/helpers/transltaion_helper/localization'使用localize,不是吗?这可能会变得有点麻烦
  • @AlbertCatalà 对于这种情况,您可以将 lib 添加到您的 autoload_path:stackoverflow.com/a/19650564/33226 如果尚未完成,这通常是我为 Rails 项目做的第一件事。不知道为什么 rails 默认不这样做。
  • 谢谢!为所有人。
  • @AlbertCatalà 您可以通过将config.eager_load_paths &lt;&lt; Rails.root.join('lib') 添加到您的config/application.rb 来预先加载lib 文件夹。急切加载时,您可以删除 require 语句。
  • 不要将 lib 目录添加到 app 目录中,它们都有不同的用途。可以在Getting Started with Rails 指南中找到对不同目录的说明。
猜你喜欢
  • 2012-05-31
  • 2023-03-21
  • 2011-01-13
  • 1970-01-01
  • 1970-01-01
  • 2010-11-04
  • 1970-01-01
  • 2019-07-01
  • 1970-01-01
相关资源
最近更新 更多