ruby-on-rails - 在 lib 目录的模块中使用类 - Rails 3

标签 ruby-on-rails

我在 lib 目录中有一个设置,如下所示:

lib/
  copy_process.rb
  copy_process/
    processor.rb

copy_process.rb 和 processor.rb 包含模块定义 CopyProcess。 copy_process.rb 也定义了 CopyFile 类:

module CopyProcess
  class CopyFile
  end
end

processor.rb 的结构如下:

module CopyProcess
  class Processer

  end
end

在其中一个方法中,它创建了一个新的复制文件对象:

def append_file_if_valid(file_contents, headers, files, file_name)
  unless headers
    raise "Headers not found"
  else
    files << CopyProcess::CopyFile.new()
  end
end

当我将这些文件用作命令行 ruby​​ 程序的一部分时,它运行良好。但是,我开始将它放入 Rails 应用程序中,并且我编写了 Cucumber/capybara 测试来点击按钮等使用它的地方。我从我的一个 AR 模型中初始化一个 Processor 对象,并多次调用上述方法。它似乎找不到 CopyFile 类,即使我的 application.rb 中有以下代码

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

有什么想法吗?

============================================= ================

编辑 上面的问题是通过将复制文件类提取到它自己的 lib 文件中来解决的。 我现在有另一个问题:

CopyFile 类引用位于 lib/copy_process.rb 中的模块级辅助方法,如下所示:

module CopyProcess
  # Gets the index of a value inside an array of the given array
  def get_inner_index(value, arr)
    idx = nil
    arr.each_with_index do |e, i|
      if e[0] == value
        idx = i
      end
    end
    return idx
  end

  def includes_inner?(value, arr)
    bool = false
    arr.each { |e| bool = true if e[0] == value  }
    return bool
  end


  # Encloses the string in double quotes, in case it contains a comma
  # @param [String] - the string to enclose
  # @return [String]
  def enclose(string)
    string = string.gsub(/\u2019/, '&rsquo;')
    if string.index(',')
      return "\"#{string}\""
    else
      return string
    end
  end
end

当我运行我的 cucumber 测试时,出现以下错误:

 undefined method `includes_inner?' for CopyProcess:Module (NoMethodError)
  ./lib/copy_process/copy_file.rb:64:in `set_element_name_and_counter'

这里指的是这个方法:

def set_element_name_and_counter(element_names, name)
  if !CopyProcess::includes_inner?(name, element_names)
    element_names << [name, 1]
  else
    # if it's in the array already, find it and increment the counter
    current_element = element_names[CopyProcess::get_inner_index(name, element_names)]
    element_names[CopyProcess::get_inner_index(name, element_names)] = [current_element[0], current_element[1]+1]
  end
  element_names
end

我还尝试将 lib/copy_process/目录中的 copy_file.rb 和其他文件向上移动到 lib 目录中。然后我收到以下错误:

 Expected /Users/aaronmcleod/Documents/work/copy_process/lib/copy_file.rb to define CopyFile (LoadError)
  ./lib/processor.rb:48:in `append_file_if_valid'

错误声明的行创建了一个 CopyFile 实例。我猜 rails 不喜欢以这种方式加载文件,对于以前的设置,我认为 copy_file.rb 在加载模块的其余部分时遇到问题。我试过要求它等等,但没有运气。您还可以在这里找到我最近的代码:https://github.com/agmcleod/Copy-Process/tree/rails

最佳答案

首先 config.autoload_paths += %W(#{config.root}/lib) 应该足够了。这会告诉 Rails 开始在/lib 中寻找结构正确的文件。

其次,我认为您遇到了问题,因为 CopyFile 不是 Rails 期望的位置。据我所知,您的设置“应该”有效,但您是否尝试过将 CopyFile 分离到 copy_process 文件夹下的自己的文件中?我的猜测是,因为 copy_process 文件夹存在,所以它期望所有 CopyProcess::* 类都在那里定义,而不是 copy_process.rb。

编辑:您可以考虑打开另一个问题,但问题的后半部分完全是一个不同的问题。

您可以像这样在模块中定义方法,

module X
  def method_one
    puts "hi"
  end
end

这种形式的方法是模块上的实例方法,它们有非常特殊的限制。例如,您不能从模块定义之外访问它们(我怀疑它们以前是如何工作的)。执行上面给出

> X::method_one
NoMethodError: undefined method `method_one' for X:Module

如果您想从其他范围访问这些方法,您有几个选择。

使用类方法

 module X
   def self.method_one
     puts "hi"
   end
 end
 X::hi #=> "hi"

使用Mixins

module X
  module Helpers
    def method_one
      puts "hi"
    end
  end
end

class CopyFile
  include X::Helpers

  def some_method
    method_one #=> "hi"
    self.method_one #=> "hi"
  end
end

关于ruby-on-rails - 在 lib 目录的模块中使用类 - Rails 3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6930018/

相关文章:

javascript - 在 AngularJS 模板中使用 Rails 助手

ruby-on-rails - rails : Reloading code in development environment gives a "ApplicationHelper has been removed from the module tree but is still active!" error

ruby-on-rails - 生产盒上的 Sqlite

ruby-on-rails - 用于跟踪用户事件的 Gem

sql - 对包含变量进行分页

ruby-on-rails - 在谷歌地图上动态显示标记-Rails 3.2

ruby-on-rails - 良好实践——模型中的重定向? -- rails 3.1

ruby-on-rails - 没有要加载的文件,模型/库命名冲突?

ruby-on-rails - rails 3 : User input escaping working differently in views and mailer

ruby-on-rails - Rails 初始化程序中的两个线程无法正常工作