2011-02-24 10 views
8

tengo una clase base heredado por otros 2 a través de tabla única herencia. Quiero que todas las subclases compartan el mismo controlador/vistas por varias razones: la única diferencia real está en la funcionalidad del modelo.Controller individuales, múltiples (heredado) clases (carriles 3)

Sin embargo, cuando intento utilizar link_to "cosas", instance_of_child me sale quejas por no poder encontrar la página correcta.

He intentado jugar con match '/ subclass' => redirigir ('/ parent') pero eso produce enlaces extraños que no tienen sentido. ¿Alguna sugerencia? Soy bastante nuevo en los rieles, y admito que mi comprensión de routes.rb es aún limitada, sin embargo, no estoy del todo seguro de que sea donde debería estar mirando.

Respuesta

12

De http://www.alexreisner.com/code/single-table-inheritance-in-rails:

Si alguna vez has intentado añadir a una ITS carriles existentes aplicación que probablemente sabe que muchos de sus link_to y form_for métodos emiten errores cuando se agrega una clase padre . Esto se debe a ActionPack mira la clase de un objeto para determinar su camino y URL, y todavía no rutas asignadas para sus nuevas subclases. Puede agregar las rutas como tal, aunque No recomiendo que:

# NOT recommended: 
map.resources :cars,  :as => :vehicles, :controller => :vehicles 
map.resources :trucks,  :as => :vehicles, :controller => :vehicles 
map.resources :motorcycles, :as => :vehicles, :controller => :vehicles 

Esto sólo alivia un síntoma particular . Si utilizamos form_for, nuestros campos de formulario seguirán sin tener los nombres que esperamos (por ejemplo: params [:] [coches]: color en lugar de params [: vehículos] [: color]). En cambio, debemos atacar la raíz de el problema mediante la aplicación del método de nombre_del_modelo en nuestra clase padre. no he visto ninguna documentación para esta técnica, por lo que este es muy no oficial, pero tiene sentido y es funciona perfectamente para mí en Rails 2.3 y 3:

def self.inherited(child) 
    child.instance_eval do 
    def model_name 
     Vehicle.model_name 
    end 
    end 
    super 
end 

Este probablemente se ve confuso, así que vamos a explicar :

Cuando se llama a un método de generación de URL (por ejemplo: link_to ("coche", coche)), ActionPack modo llamadas l_name en la clase del objeto dado (aquí carro). Esto devuelve un tipo especial de cadena que determina lo que el objeto se llama en las direcciones URL. Todo lo que hacemos aquí es reemplazando el método nombre_del_modelo para subclases de vehículo por lo ActionPack verá automóvil, camión y moto subclases como pertenecientes a la clase padre (Vehículo), y por lo tanto utilizar rutas con nombre de la clase padres (VehiclesController) donde quiera que se generen las URL . Todo esto supone que usted es usando las URL de recursos de Rails (RESTful) . (Si no es así, por favor hazlo.)

Para investigar la invocación nombre_del_modelo ti mismo, ver el código fuente de Rails para la método ActionController :: RecordIdentifier # model_name_from_record_or_class. En Rails 2.3 la cadena especial es una instancia de ActiveSupport :: ModelName, en Rails 3 es una ActiveModel :: Nombre

+0

Esto es exactamente lo que estaba buscando. Jugar con la tabla de enrutamiento parecía una mala solución, y sí, me había dado cuenta de que estaba estropeando mis formularios. Entonces, con solo una ligera modificación en el ejemplo anterior para que se ajuste al nombre de mi clase, su solución resolvió mis problemas. No tienes idea de cuánto temía crear/mantener esos controladores adicionales. – user632657

+0

¡Me alegra oírlo! :) –

Cuestiones relacionadas