轨道/ lib中的模块和轨道/ lib中的模块和(Rails /lib modules and)

2019-05-14 11:42发布

我写了一个自定义包装open_flash_chart插件。 它放置在/lib ,并加载它作为一个模块ApplicationController

不过,我有一些类层次结构或不便的问题。

从任何控制器我可以访问open_flash_chart功能OpenFlashChartLine

然而,在一个类中的/lib模块,它不工作!

有任何想法吗?

Answer 1:

有迹象表明,文件Rails中得到加载两种方式:

  • 它是注册在自动加载的过程,您引用对应于文件名的常量。 举例来说,如果你有app/controllers/pages_controller.rb和参考PagesController, app/controllers/pages_controller.rb会自动加载。 这发生在负载路径目录的预设列表。 这是轨道的特征,并且不是一般的Ruby负载过程的一部分。
  • 文件明确require d。 如果文件是require d,红宝石看起来通过在负载路径路径的整个列表,并找到你的文件,第一种情况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

当然,为了能够包括在第一位的模块,你就需要把它可用(使用的技术之上)。



Answer 2:

在Rails 3 / lib中模块没有自动加载。

这是因为该行:

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

内部配置/ application.rb中被注释。

你可以试着去掉这一行,或者(它为我工作更好),离开这个评论(备查),并添加这两条线:

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


Answer 3:

什么工作对我来说,除了在取消config.autoload_paths(我on Rails的3.1.3),是要创造一个像这样的初始化:

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

这样我可以调用MyModule的方法在任何地方和类方法Model.mymodule_method或实例方法mymodel.mymodule_method

也许有些专家可以解释这意味着什么。 现在,在你自己的风险使用它。

编辑:后来,我想一个更好的approuch是:

创建这样的初始化:

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

包括在需要的地方,这样的模块:

1)如果你想使用它作为“类方法”使用“扩展”:

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在你的负载路径,必须首先要求



Answer 4:

要使用该模块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



Answer 5:

这可能是你想在应用程序初始化的时间显式地加载lib目录下的文件(S)的情况下。
在我的config / application.rb中,我有一个条目,
config.autoload_paths += %W(#{config.root}/lib)

这也可能是模块名称/层次是不相同的情况下,因为它是在文件或位置/文件名不一样的层次结构,使文件自动负载也是不可能的。 所以,当我在配置/ application.rb中为底部增加了一个入口,
require "./lib/file_name_without_extention
它工作得很好。



文章来源: Rails /lib modules and