rails - autoload_paths文件夹中的文件未加载

时间:2018-05-24 11:56:32

标签: ruby-on-rails

我有一个app/extensions文件夹,我的自定义异常位于该文件夹中,并且我扩展了一些Ruby / Rails类。目前有两个文件:exceptions.rbfloat.rb

该文件夹在ActiveSupport::Dependencies.autoload_paths

中指定
/Users/mityakoval/rails/efo/app/extensions/**
/Users/mityakoval/rails/efo/app/assets
/Users/mityakoval/rails/efo/app/channels
/Users/mityakoval/rails/efo/app/controllers
/Users/mityakoval/rails/efo/app/controllers/concerns
/Users/mityakoval/rails/efo/app/extensions
/Users/mityakoval/rails/efo/app/helpers
/Users/mityakoval/rails/efo/app/jobs
/Users/mityakoval/rails/efo/app/mailers
/Users/mityakoval/rails/efo/app/models
/Users/mityakoval/rails/efo/app/models/concerns
/Users/mityakoval/rails/efo/app/template.xlsx
/Users/mityakoval/.rvm/gems/ruby-2.4.1@web_app/gems/font-awesome-rails-4.7.0.2/app/assets
/Users/mityakoval/.rvm/gems/ruby-2.4.1@web_app/gems/font-awesome-rails-4.7.0.2/app/helpers
/Users/mityakoval/rails/efo/test/mailers/previews

它在那里列出两次的原因是它应该被自动加载,因为它被放在app目录下,我还手动将它添加到autoload_paths中的application.rb

config.autoload_paths << File.join(Rails.root, 'app', 'extensions/**')

奇怪的是我的exceptions.rb已成功加载,但float.rb除非启用了预先加载,否则spring.rb不会。

this question的答案说它可能与Spring(我倾向于相信)有关,所以我已将该文件夹添加到%w( .ruby-version .rbenv-vars tmp/restart.txt tmp/caching-dev.txt config/application.yml app/extensions ).each { |path| Spring.watch(path) }

/Users/mityakoval/rails/efo/app/extensions/float.rb

我已多次重启Spring和Rails服务器,但没有任何效果。有没有人有任何建议?

Ruby版本:2.4.1 Rails版本:5.1.5

修改

class Float def comma_sep self.to_s.gsub('.', ',') end end

irb> num = 29.1
irb> num.comma_sep
NoMethodError: undefined method `comma_sep' for 29.1:Float
    from (irb):2

rails console:

eu-west-1

1 个答案:

答案 0 :(得分:1)

monkeypatch核心类的一个更好的方法是创建一个模块并将其包含在要在初始化程序中修补的类中:

# /lib/core_extensions/comma_seperated.rb
module CoreExtensions
  module CommaSeperated
    def comma_sep
      self.to_s.gsub('.', ',')
    end
  end
end
# /app/initializers/core_extensions.rb
require Rails.root.join('lib', 'core_extensions', 'comma_seperated')

# or to require all files in dir:
Dir.glob(Rails.root.join('lib', 'core_extensions', '*.rb')).each do |f|
  require f
end


Float.include CoreExtensions::CommaSeperated

请注意,这里我们根本没有使用Rails自动加载器并明确要求补丁。另请注意,我们将文件放在/lib而不是/app。任何非特定于应用程序的文件都应放在/lib

将猴子补丁放在模块中可让您通过将代码包含在任意类中来测试代码。

class DummyFloat

  include CoreExtensions::CommaSeperated

  def initialize(value)
    @value = value
  end

  def to_s
    @value.to_s
  end
end

RSpec.describe CoreExtensions::CommaSeperated do
  subject { DummyFloat.new(1.01) }
  it "produces a comma seperated string" do
    expect(subject.comma_sep).to eq "1,01"
  end
end

这也提供了更好的堆栈跟踪,并且可以更容易地关闭和打开猴子补丁。

但在这种情况下,我认为你一开始并不需要它--Rails有很多帮手可以人性化并定位ActionView::Helpers::NumberHelper中的数字。 NumberHelper也正确地提供了帮助方法,而不是monkeypatching核心Ruby类,这通常是最好的避免。

请参阅: