4

当您使用 rails 脚手架创建命名空间模型时,您会得到两个文件。例如,这个脚手架:

rails generate model Staff::Location name:string address:string

生成这些文件:

/app/models/staff.rb    
module Staff
  def self.table_name_prefix
    "staff_"
  end
  ...

/app/models/staff/location.rb
class Staff::Location < ActiveRecord::Base
  ...

在开发模式下,rails 卸载 Staff 模块并且从不重新加载它时,我遇到了问题。这会导致一些烦人的错误,例如 Location 由于缺少 table_name_prefix 而无法访问它的表。当我不直接访问模型时,问题似乎出现了,例如通过多态关系。

我似乎无法以一致的方式加载模块。这是做命名空间模型的最佳实践方式吗?如果是,我错过了什么?

4

2 回答 2

2

尽管我无法在 Rails 3.2.2 中重现该问题,但我之前遇到过类似的情况。在开发模式下解决此问题的通用方法是通过ActionDispatch回调。将此添加到config/environments/development.rb

MyApp::Application.configure do
  ActionDispatch::Callbacks.before do
    load Rails.root.join('app', 'models', 'staff.rb')
  end
end

您在该块中所做的任何事情都将在每个请求之前执行,因此请确保您仅在开发模式下执行此操作。†否则,您将在生产中遭受性能影响。

我在staff.rb文件和Staff模块本身中记录了一条消息,两条消息都出现在每个请求的日志中。


†我尝试使用to_prepare回调,因为这似乎是在每个请求之前执行代码的记录方式,只有当cache_classes是 false时。但这似乎只有在重新启动应用程序后才会执行。至少还有一个关于此的其他未解决的 Stack Overflow 问题,尽管他使用的语法与我使用的略有不同。如果您可以to_prepare上班,我建议您不要使用before.

于 2012-04-15T01:02:07.117 回答
2

大约一年后,我终于找到了这个问题的答案。这个答案专门针对rails 3.1。我不确定这是否是 rails 3.2 中的问题。

设置模型时会出现问题。如果使用脚手架,则不会生成帮助文件。这通常位于 /app/helpers/staff/location_helper.rb 中。有两种方法可以设置此文件:

module Staff::LocationHelper
  ...
end

module Staff
  module LocationHelper
    ...
  end
end

在 rails 3.1 中,特别是对于助手,您必须使用第一个解决方案。您不必将它用于在 rails 项目的其他部分中使用命名空间的其他模块。事实上,ruby 中的某些结构需要第二种解决方案。

如果在声明助手时使用第二种解决方案,在某些情况下,助手文件中的 Staff 模块将覆盖 /app/models/staff.rb 中的模块。它将默默地用文件中的空 Staff 模块替换它。这不会 100% 发生,因为助手并不总是被加载。

于 2013-03-21T15:01:35.823 回答