在Rails 5项目中,何处放置重定义类文件以及如何配置它们?

时间:2018-11-22 14:45:40

标签: ruby-on-rails

问题的重新修订(在加文·米勒(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

并建议将Gavin Miller对我说过的所有lib/core_extensions文件夹放在app/lib/文件夹下,除此之外,什么也不要,但是除非我require全部文件,但这不是必需的,因为app中的所有内容都是自动加载的。

我想我缺少一些配置

这是图像,更易于解释

enter image description here

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

1 个答案:

答案 0 :(得分:1)

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

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

请查看您的特定文件,

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

FormWithBuilder不是核心扩展,而是子类。 lib是适当的表述方式,但不要混淆子类和核心扩展的思想,它们是两个截然不同的构造,它们的用途不同。