代码之家  ›  专栏  ›  技术社区  ›  Vincent

从Rails3的lib文件夹加载模块/类的最佳方法是什么?

  •  269
  • Vincent  · 技术社区  · 14 年前

    由于最新的Rails3版本不再从lib自动加载模块和类, 装载它们的最佳方式是什么?

    从github:

    A few changes were done in this commit:
    
    Do not autoload code in *lib* for applications (now you need to explicitly 
    require them). This makes an application behave closer to an engine 
    (code in lib is still autoloaded for plugins);
    
    12 回复  |  直到 14 年前
        1
  •  252
  •   user664833 Ronen Rabinovici    13 年前

    As of Rails 2.3.9 ,中有一个设置 config/application.rb

    从application.rb:

    # Custom directories with classes and modules you want to be autoloadable.
    # config.autoload_paths += %W(#{config.root}/extras)
    
        2
  •  200
  •   typeoneerror    11 年前
    # Autoload lib/ folder including all subdirectories
    config.autoload_paths += Dir["#{config.root}/lib/**/"]
    

    资料来源: Rails 3 Quicktip: Autoload lib directory including all subdirectories, avoid lazy loading

    请注意,lib文件夹中包含的文件仅在服务器启动时加载。如果您想轻松地自动读取这些文件,请阅读: Rails 3 Quicktip: Auto reload lib folders in development mode . 请注意,这并不适用于生产环境,因为永久重新加载会降低机器的速度。

        3
  •  84
  •   Brad Werth    9 年前

    自动加载的魔力

    因此,当从子目录加载内容时,有一个gotcha或约定你应该知道。有时候Ruby/Rails的魔力(这次主要是Rails)会让人很难理解为什么会发生这样的事情。只有当模块名与父目录名对应时,才会加载自动加载路径中声明的任何模块。所以万一你想 lib/my_stuff/bar.rb

    module Foo
      class Bar
      end
    end
    

    foo 因此,将模块托管在路径: lib/foo/bar.rb . 它会为你而存在。另一个选项是用模块名命名要自动加载的文件。很显然,只有一个文件的名称,然后。如果你需要将你的东西分割成许多文件,你当然可以使用一个文件来要求其他文件,但我不建议这样做,因为当你在开发模式下修改其他文件时,Rails无法自动为你重新加载它们。但是如果您真的需要,您可以有一个模块名的文件,然后指定使用该模块所需的实际文件。所以你可以有两个文件: lib/my_stuff/foo.rb require "bar"

    另外,我觉得有必要再补充一件重要的事情。最近,每当我想在lib目录中有需要自动加载的东西时,我往往会开始想,如果这是我为这个项目专门开发的东西(通常是这样的,有朝一日它可能会变成许多项目中使用的“静态”代码片段或git子模块等)。。在这种情况下,它肯定应该在lib文件夹中),那么它的位置可能根本就不在lib文件夹中。也许它应该在app文件夹下的一个子文件夹里。我有种感觉,这是rails新的做事方式。很明显,同样的魔力也在工作,无论你把你的东西放在什么自动加载路径上,这样对这些东西都有好处。不管怎样,这只是我对这个问题的看法。你可以不同意


    正如severin在他的评论中指出的,核心“自动加载模块机制”当然是Ruby的一部分,但自动加载路径的东西不是。你不需要栏杆 autoload :Foo, File.join(Rails.root, "lib", "my_stuff", "bar")

        4
  •  41
  •   Community CDub    8 年前

    'autoload' approach !!!

    • " config.autoload_paths “方法:仅在加载仅在一个位置定义的类时有效。如果某个类已经在其他地方定义过,那么您就不能用这种方法再次加载它。

    • config/initializer/load_rb_file.rb “方法:始终有效!无论目标类是新类还是现有类的“开放类”或“猴子补丁”,它总是有效的!

    有关详细信息,请参阅: https://stackoverflow.com/a/6797707/445908

        5
  •  28
  •   Brian Armstrong    13 年前

    非常相似,但我觉得这更优雅一点:

    config.autoload_paths += Dir["#{config.root}/lib", "#{config.root}/lib/**/"]
    
        6
  •  18
  •   Nick Res    11 年前

    在我的例子中,我试图直接在lib dir下加载一个文件。

    在application.rb中。。。

    require '/lib/this_file.rb' 
    

    不起作用,即使在控制台里

    require './lib/this_file.rb' 
    

    rails完美地加载了文件。

    我还是个笨蛋,我不知道为什么这么做有效,但确实有效。如果有人愿意向我解释,我将不胜感激:我希望这对任何人都有帮助。

        7
  •  7
  •   Dave Newton    12 年前

    # application.rb
    config.autoload_paths += %W(#{config.root}/lib)
    config.autoload_paths += Dir["#{config.root}/lib/**/"]
    
        8
  •  5
  •   Dave Newton    12 年前

    config.autoload\u路径对我不起作用。我用另一种方法解决它

    rubyonrails3不会从/lib文件夹自动重新加载(autoload)代码。我把它放进去解决 ApplicationController

    Dir["lib/**/*.rb"].each do |path|
      require_dependency path
    end 
    
        9
  •  5
  •   Ashik Salman    7 年前

    截至 Rails 5 ,建议将lib文件夹放在app directory下,或者为该文件夹创建其他有意义的名称空间 services , presenters features etc并将其放在app目录下,以便通过rails自动加载。

    请检查这个 GitHub Discussion Link 也。

        10
  •  4
  •   Mike Fischer    14 年前

    require 'mymodule'
    

    在model.rb文件的顶部。

        11
  •  2
  •   David Hempy    7 年前

    正确拼写文件名。

    说真的。我和一个类争了一个小时,因为这个类是Governance::ArchitectureBoard,文件位于lib/Governance/architecture\u baord.rb(在“board”中转置了O和a)

        12
  •  1
  •   Chris Kimpton    12 年前

    从lib加载时可能出现问题的原因有很多-请参阅此处了解详细信息- http://www.williambharding.com/blog/technology/rails-3-autoload-modules-and-classes-in-production/

    • 线程安全相关