缺少Rails table_name_prefix

我有以下目录结构

models/foo/setting.rb models/foo.rb 

foo.rb内容

  module Foo def self.table_name_prefix 'foo_' end end 

和setting.rb内容

 class Foo::Setting < ActiveRecord::Base end 

一旦我调用Foo::Setting.find…我收到一个错误SQLException: no such table: settings确实是正确的,因为该表名为foo_settings所以rails似乎忽略为模块Foo指定的表前缀。

我可以做什么让rails考虑前缀?

您已在模块(Foo)中定义了一个方法。 这并没有神奇地在嵌套在该模块中的类上定义该方法。

我会尝试类似的东西

 class Foo < ActiveRecord::Base self.abstract_class = true self.table_name_prefix = 'foo_' end 

然后从Fooinheritance

 class Foo::Setting < Foo ... end 

这可能是由rails的自动加载器引起的。 这样做时:

 module Foo class Bar end end 

然后尝试使用Foo::Bar ,自动加载器首先尝试找到app/models/foo/bar.rb 文件已加载,此处定义了module Foo (虽然是一个仅包含Bar的模块),因此自动加载器从不尝试加载app/models/foo.rb

这应该只在开发模式下进行,因为在生产模式下,所有文件都require在启动时使用。

AFAIK有两种解决方法:

欺骗自动加载器

使用class Foo::Bar声明您的类,强制自动加载器解析Foo的常量查找。

这有令人讨厌的副作用, Bar内的常量查找不会限制在Foo ,例如:

 # app/models/foo.rb module Foo BAZ = "baz" end # app/models/foo/bar.rb class Foo::Bar def baz BAZ end end 

在这里, Foo::Bar.new.baz会失败,除非你使用Foo::BAZ引用常量。 例如,在定义ActiveRecord关联时,这可能会变得非常混乱。

需要模块

使用require_dependency

 require_dependency 'foo' module Foo class Bar end end 

这是恕我直言的正确解决方案,因为它不会破坏常量查找,但它也有点烦人,因为你必须在每个命名空间文件的顶部添加require语句。

注意 :

这个bug似乎已经在rails 4中解决了。我在rails 3上使用了第二个解决方法,但是我试图重现rails 4中的bug并且它不再出现了。 我认为他们修改了自动加载器的工作方式…有关详细信息,请参阅自动加载和重新加载常量的rails指南

我遇到过同样的问题。 通过更改我的应用程序的命名空间或模型来解决它。

看看这个问题 。 对应用程序使用与模型相同的命名空间会导致模型无法正确获取父命名空间table_name_prefix。

只需在命名空间的模型目录中创建一个基类,并在其中需要Foo,然后从基类扩展模型。

说我有app/models/foo.rb

 module Foo def self.table_name_prefix 'tble_prefix_' end end 

然后在app/models/foo/base_record.rb

 require_dependency 'foo' module Foo class BaseRecord < ActiveRecord::Base self.abstract_class = true end end 

然后从BaseRecord扩展

 module Foo class Bar < BaseRecord end end