rails mvc initialize create belong association and active ruby-on-rails model module prefix

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.