ruby-on-rails - initialize - ruby on rails mvc
Rails table_name_prefix faltan (4)
Tengo la siguiente estructura de directorio
models/foo/setting.rb
models/foo.rb
contenido foo.rb
module Foo
def self.table_name_prefix
''foo_''
end
end
y setting.rb contenido
class Foo::Setting < ActiveRecord::Base
end
Tan pronto como estoy llamando a Foo::Setting.find…
Recibo un error SQLException: no such table: settings
que son correctas porque la tabla se llama foo_settings
por lo que los rieles parecen ignorar el prefijo de tabla especificado para el módulo Foo.
¿Qué puedo hacer para que los rieles consideren el prefijo?
Esto es probablemente causado por el autoloader de rieles. Al hacer esto:
module Foo
class Bar
end
end
Y luego, tratando de usar Foo::Bar
, el autocargador primero intenta localizar app/models/foo/bar.rb
El archivo se carga y el module Foo
se define aquí (aunque como un módulo que contiene únicamente la Bar
), por lo que el autocargador nunca intenta cargar la app/models/foo.rb
Esto solo debería suceder en el modo de desarrollo, ya que en el modo de producción todos los archivos se require
al inicio.
Hay dos soluciones AFAIK:
Engañar al autoloader
declare su clase usando la class Foo::Bar
, para forzar al autocargador a resolver una búsqueda constante de Foo
.
Esto tiene el efecto secundario molesto de que la búsqueda constante dentro de la Bar
NO se alcance dentro de Foo
, por ejemplo:
# app/models/foo.rb
module Foo
BAZ = "baz"
end
# app/models/foo/bar.rb
class Foo::Bar
def baz
BAZ
end
end
aquí, Foo::Bar.new.baz
fallará, a menos que haga referencia a la constante utilizando Foo::BAZ
. Esto puede ser realmente un desastre al definir asociaciones ActiveRecord, por ejemplo.
Requerir el modulo
utilizando require_dependency
:
require_dependency ''foo''
module Foo
class Bar
end
end
En mi opinión, esta es la solución correcta, ya que no rompe la búsqueda constante, pero también es un poco molesto, ya que tiene que agregar la declaración de requerimiento sobre cada archivo con espacio de nombre.
Nota :
Parece que este error se resolvió en los rieles 4. Utilicé la segunda solución mucho mientras estaba en los rieles 3, pero he intentado reproducir el error en los rieles 4 y ya no aparece. Creo que modificaron la forma en que funciona el autocargador ... Para obtener más información, consulte las guías de rieles sobre la carga automática y la carga de las constantes
Has definido un método dentro de un módulo (Foo). Esto no define mágicamente ese método en una clase anidada en ese módulo.
Probaría algo como
class Foo < ActiveRecord::Base
self.abstract_class = true
self.table_name_prefix = ''foo_''
end
Y luego heredar de Foo
class Foo::Setting < Foo
...
end
Simplemente cree una clase base dentro de su directorio de modelos con espacios de nombre y requiera Foo en él, luego extienda sus modelos desde la clase base.
Digamos que tengo app/models/foo.rb
module Foo
def self.table_name_prefix
''tble_prefix_''
end
end
Luego en app/models/foo/base_record.rb
require_dependency ''foo''
module Foo
class BaseRecord < ActiveRecord::Base
self.abstract_class = true
end
end
Luego BaseRecord
desde el BaseRecord
module Foo
class Bar < BaseRecord
end
end
Tuve el mismo problema. Se solucionó cambiando el espacio de nombres de mi aplicación o el del modelo.
Echa un vistazo a esta question . El uso del mismo espacio de nombres para la aplicación que para los modelos hace que los modelos no recojan el espacio de nombres padre table_name_prefix correctamente.