I have got the following dir structure
models/foo/setting.rb
models/foo.rb
foo.rb content
module Foo
def self.table_name_prefix
'foo_'
end
end
and setting.rb content
class Foo::Setting < ActiveRecord::Base
end
As soon as I am calling Foo::Setting.find…
I am getting an error SQLException: no such table: settings
which is indeed correct because the table is named foo_settings
so rails seems to ignore the table prefix specified for the module Foo.
What can I do so that rails considers the prefix?
You've define a method inside a module (Foo). This doesn't magically define that method on a class nested in that module.
I'd try something like
class Foo < ActiveRecord::Base self.abstract_class = true self.table_name_prefix = 'foo_' end
And then inherit from Foo
class Foo::Setting < Foo ... end
This is probably caused by rails' autoloader. When doing this :
module Foo
class Bar
end
end
And then trying to use Foo::Bar
, the autoloader first tries to locate app/models/foo/bar.rb
. The file is loaded, and module Foo
is defined here (albeit as a module containing solely Bar
) so the autoloader never attempts to load app/models/foo.rb
.
This should only happen in development mode, as in production mode all of your files are require
'd on startup.
There are two workarounds AFAIK :
Cheat the autoloader
declare your class using class Foo::Bar
, to force the autoloader to resolve a constant lookup for Foo
.
This has the annoying side effect that the constant lookup inside Bar
will NOT be scoped inside Foo
, for instance :
# app/models/foo.rb
module Foo
BAZ = "baz"
end
# app/models/foo/bar.rb
class Foo::Bar
def baz
BAZ
end
end
here, Foo::Bar.new.baz
will fail, unless you reference the constant using Foo::BAZ
. This can get really a mess when defining ActiveRecord associations, for instance.
Require the module
using require_dependency
:
require_dependency 'foo'
module Foo
class Bar
end
end
This is IMHO the right solution, as it does not break the constant lookup, but it is also a bit annoying as you have to add the require statement on top of each namespaced file.
Note :
This bug seems to have been resolved in rails 4. I used the second workaround a lot while on rails 3, but I've tried to reproduce the bug in rails 4 and it does not show up anymore. I think they modified the way the autoloader works... For more info, see the rails guides on autoloading and reloading constants
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With