【问题标题】:Losing namespace information in a rails namespaced model在 Rails 命名空间模型中丢失命名空间信息
【发布时间】:2012-04-18 04:51:35
【问题描述】:

当您使用 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 而无法访问它的表。当我不直接访问模型时,例如通过多态关系,问题似乎出现了。

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

【问题讨论】:

  • 你能举一个产生这个错误的代码的例子吗?也许是似乎经常失败的关系之一?

标签: ruby-on-rails activerecord namespaces


【解决方案1】:

大约一年后,我终于找到了这个问题的答案。这个答案专门针对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% 发生,因为助手并不总是被加载。

【讨论】:

    【解决方案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 回调,因为那似乎是the documented way to execute code before each request only when cache_classes is false。但这似乎只有在重新启动应用程序后才会执行。至少有one other open Stack Overflow question regarding this,尽管他使用的语法与我使用的略有不同。如果您可以让to_prepare 工作,我建议您不要使用before

    【讨论】:

      猜你喜欢
      • 2012-09-10
      • 2017-03-21
      • 2012-07-08
      • 2011-05-23
      • 2011-08-16
      • 1970-01-01
      • 2013-05-28
      • 2020-09-13
      • 2012-02-16
      相关资源
      最近更新 更多