首页 > 解决方案 > 在 Rails 5 项目中,在哪里放置重定义类文件,以及如何配置它们?

问题描述

重新编辑问题(在 Gavin Miller 之后并感谢 Gavin Miller)

如果 a 具有三种核心扩展(或猴子补丁),例如以下示例:

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

并建议将lib/core_extensionsGavin Miller 对我说的所有这些文件夹放在文件夹下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 编辑

这是一个糟糕的解决方案吗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

解决方案


您所说的重新定义称为核心扩展(或猴子补丁),并被放入名为core_extensions. 这样,您就可以将每个功能分解为单独的文件,而不是在单个文件中包含大量不同的功能。Rails 项目说明了我所说的文件夹结构。

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

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

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

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


推荐阅读