Rails app和Rake之间的类名冲突

时间:2017-08-16 21:13:05

标签: ruby-on-rails ruby rake

我的Rails 4应用程序中有一个k模型,它的开头是这样的:

Document

class Document < ActiveRecord::Base TYPES = [FileList, Article, VariantList, LinkedItemsList].collect(&:model_name) ... end 数组在我的应用程序中包含其他模型的列表,并在一些地方使用,例如在我的一个表单中显示可能的文档类型列表。

现在我正在写一个Rake任务来自动化一些东西,当我运行任务时,我在Document模型的第2行得到了这个错误:

TYPES

显然,首先加载了NoMethodError: undefined method 'model_name' for Rake::FileList:Class类,并且我得到名称冲突。在我的代码中使用Rake::FileList没有帮助,我得到了同样的错误。

知道如何在不重命名模型的情况下解决这个问题吗?

更新

My Rake任务定义如下所示:

::FileList

我认为这是正确加载环境,因为我在调用namespace :store do desc 'Some description' task :my_task_name, [:a_parameter_name] => [:environment] do |t, args| ... end end 之前正在调用(从DB加载)其他一些模型并且这样做正常。

2 个答案:

答案 0 :(得分:0)

有人认为你可以尝试在类定义结束时给它foos.id添加一个别名:

FileList

然后在您的佣金访问class FileList < ActiveRecord::Base ... end FileListCopy = FileList

答案 1 :(得分:0)

当您从Document模型调用FileList时,它会尝试按以下顺序解析此常量:

  1. 它试图在Module.nesting链的元素中找到常量。在您的情况下,嵌套仅为[Document],并且不包含FileList常量。
  2. 然后它试图在对象的祖先中找到常数。
  3. 最后在Object中查找常数。
  4. Rake通过Object模块扩展FileList来全局展示其DSL。因此,在使用rake时,您总是从rake获得MyApp::FileList

    要解决此问题,您可以将所有代码移动到命名空间中。例如MyApp::Document[MyApp::Document, MyApp]。在这种情况下,常量查找算法将尝试在嵌套元素(MyApp)中找到常量。嵌套的第二个元素(FileList)包含MyApp常量。因此,它将从Rake模块而不是{{1}}解决。

    为避免此类问题,将代码放入某个命名空间始终是一个好主意。