ruby-on-rails Rails /lib模块和

mpgws1up  于 2022-12-15  发布在  Ruby
关注(0)|答案(5)|浏览(133)

我正在为open_flash_chart插件编写一个自定义 Package 器。它被放置在/lib中,并作为ApplicationController中的一个模块加载。
然而,我遇到了类层次结构的问题或其他一些问题。
我可以从任何控制器访问open_flash_chart功能,如OpenFlashChartLine等。
但是,在/lib模块中的类中,它不起作用!
有什么想法吗?

ctehm74n

ctehm74n1#

在Rails中加载文件有两种方式:

  • 它在autoload进程中注册,并且引用一个与文件名对应的常量。例如,如果您有app/controllers/pages_controller.rb并引用PagesController,则会自动加载app/controllers/pages_controller.rb。对于加载路径中的预设目录列表,会发生这种情况。这是Rails的一个特性,而不是普通Ruby加载进程的一部分。
  • 如果文件是require d,Ruby会查看加载路径中的所有路径,并找到您require d的文件在加载路径中的第一个示例,您可以通过检查$LOAD_PATH($:的别名)来查看整个加载路径。

由于lib位于加载路径中,因此有两个选项:要么使用与常量相同的名称来命名文件,这样当您引用所讨论的常量时Rails会自动拾取它们,要么显式地要求使用该模块。
我还注意到,您可能会对另一件事感到困惑。ApplicationController不是系统中的根对象。注意:

module MyModule
  def im_awesome
    puts "#{self} is so awesome"
  end
end

class ApplicationController < ActionController::Base
  include MyModule
end

class AnotherClass
end

AnotherClass.new.im_awesome
# NoMethodError: undefined method `im_awesome' for #<AnotherClass:0x101208ad0>

您需要将该模块包含到您想要使用它的任何类中。

class AnotherClass
  include MyModule
end

AnotherClass.new.im_awesome
# AnotherClass is so awesome

当然,为了能够在第一时间包含模块,您需要使其可用(使用上述任一种技术)。

a1o7rhls

a1o7rhls2#

在Rails 3 /lib中,模块不会自动加载。
这是因为行:

# config.autoload_paths += %W(#{config.root}/extras)

字符串
config/application.rb内部已注解。
您可以尝试取消对这一行的注解,或者(对我来说效果更好),将其保留为注解(以供将来参考)并添加以下两行:

config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
l2osamch

l2osamch3#

除了取消对config.autoload_paths的注解(我使用的是Rails3.1.3)之外,对我有效的方法是创建一个初始化器,如下所示:

#config/initializers/myapp_init.rb
require 'my_module'    
include MyModule

这样,我就可以从任何地方调用mymodule方法**,作为类方法Model.mymodule_method或示例方法mymodel.mymodule_method
也许有Maven会解释这其中的含义。到现在为止,使用它的风险自担。

**编辑:**之后,我认为更好的方法是:

创建一个初始化器,如下所示:

#config/initializers/myapp_init.rb
require ‘my_module’

在需要的地方包括模块,如下所示:
1)如果你想把它作为“类方法”使用“extend”:

class Myclass < ActiveRecord::Base
   extend MyModule
   def self.method1
      Myclass.my_module_method
   end
end

2)如果您想将其用作“示例方法”,请将其包含在类定义中:

class Myclass < ActiveRecord::Base
include MyModule
   def method1
      self.my_module_method 
   end
end

3)记住include MyModule指的是加载路径中的文件my_module.rb,它必须是第一个需要的

rm5edbpk

rm5edbpk4#

要在您的模型和控制器中使用模块lib/my_module.rb
config/application.rb中:

config.watchable_dirs['lib'] = [:rb]

在您的模型中(类似于您的控制器):

require_dependency 'my_module'

class MyModel < ActiveRecord::Base
  include MyModule

  MyModule.some_method
end

http://hakunin.com/rails3-load-paths中详细介绍了此方法

5jvtdoz2

5jvtdoz25#

在应用程序初始化时,您可能希望显式加载lib目录下的文件。
在我的config/application.rb中,我有一个条目,
config.autoload_paths += %W(#{config.root}/lib)
这也可能是模块名称/层次结构不一样,因为它是在文件或位置/名称的文件是不一样的层次结构,所以自动加载该文件也是不可能的。所以当我添加了一个条目在底部的config/application.rb作为,
require "./lib/file_name_without_extention
它运行良好。

相关问题