2010-04-01 27 views
7

Mi clase de modelo es:enrutamiento anidada en Ruby on Rails

class Category < ActiveRecord::Base 
    acts_as_nested_set 
    has_many :children, :foreign_key => "parent_id", :class_name => 'Category' 
    belongs_to :parent, :foreign_key => "parent_id", :class_name => 'Category' 


    def to_param 
    slug 
    end 
end 

¿Es posible tener tal ruta recursiva como esto: /root_category_slug/child_category_slug/child_of_a_child_category_slug ... y así uno

Gracias por cualquier ayuda:)

+1

Una gran pregunta. –

Respuesta

4

Usted puede hacer eso con rutas regulares y Route Globbing, así por ejemplo,

map.connect 'categories/*slugs', :controller => 'categories', :action => 'show_deeply_nested_category' 

Luego, en su controlador

def show_deeply_nested_category 
    do_something = params[:slugs] # contains an array of the path segments 
end 

Sin embargo, tenga en cuenta que nested resource routing más de un nivel profundo, no se recomienda .

+0

Tenía la misma pregunta, y esto funciona perfectamente. Yo diría que la regla de Jamis no se aplica en este caso, ya que el recurso en sí se representa como una estructura jerárquica. (Y no hay necesidad de utilizar recursos/rutas anidados en este caso de todos modos). –

+0

Tuve que usar 'coincidencia' en lugar de 'map.connect' y funcionó perfectamente –

+0

¿Qué se debe hacer como alternativa al anidamiento de más de una profundidad? La documentación no dice. – 0112

0

No es fácil (léase: no sé cómo hacerlo) y no se recomienda. Imagine que si tiene 10 categorías, no desea que la url sea /categorya/categoryb/categoryc/categoryd/categorye/categoryf/categoryg/categoryh/categoryi/categoryj.

¿Quizás un nivel máximo de 3 le otorgaría la potencia que desea, sin contaminar la URL?

+0

Para mi nivel de opinión, el nivel debe estar limitado por el modelo, no por la regla de enrutamiento. – vooD

+0

@Ryan Bigg, ¿cómo prefieres escribir una URL para algo como esto, suponiendo que tienes n-profundidad? él está tratando de mostrar una categoría en un lugar determinado en el árbol (y podría tener otros). –

2

Lo dudo, y no es una buena idea. El código de asignación de ruta de rieles es lo suficientemente complejo sin tener que intentar codificar de forma dinámica & decodificar (posiblemente) cadenas infinitas de ruta.

1

Puede usar restricciones en el enrutamiento de rieles. por ejemplo:

match '*id', :to => 'categories#show', :constraints => TaxonConstraint.new 

class TaxonConstraint 
    def matches?(request) 
    path = request.path.slice(1..(request.path.length-1) 
    path = path.split('/') 
    return false if path.length != path.uniq.length 
    return true if Category.check(path.last).first 
    false 
    end 
end 

clase se divide en tu camino, y por cheques db "/" para último elemento en dB. si no se encuentra, omite la ruta. si alguien sabe, cómo resolverlo mejor, estaría encantado de escuchar.

+0

heh, encontré la mejor solución. luego crea una nueva categoría con acts_as_nested_set, puedes generar una ruta para rootear en 1 consulta. y luego simplemente marque el campo "ruta" => "a/b/c". – SpX