9

Estoy tratando de hacer un sitio simple de reunión familiar con: "publicaciones", "familias", "niños" y "imágenes" . Idealmente me gustaría las rutas/relaciones para ser estructurados de esta manera:Rails 3 - Recursos anidados y rutas polimórficas: OK en dos niveles, pero romper en tres

resources :posts do 
    resources :pictures 
    end 

    resources :fams do 
    resources :pictures 
    resources :kids do 
     resources :pictures 
    end 
    end 

En los modelos que tienen los necesarios "belongs_to" y "has_many" relaciones establecidas entre fams y kids. Fams, kids y posts todos se definen con "has_many :pictures, :as => :imageable ", mientras que las imágenes se definen como:. belongs_to :imageable, :polymorphic => true

Al tratar de hacer link_to "Edit" y link_to "Destroy" en los pictures vistas que me encuentro de todo tipo de _path problemas polymoric_path funciona bien en dos niveles, es decir, para posts-pictures y fams-pictures pero no puede manejar la caja de tres niveles de fams-kids-pictures. Supongo que no fue diseñado para manejar los dos niveles de objetos "imageable" por encima del objeto picture. Otra cuestión es que en una instancia, el pictures controlador tiene que manejar un recurso de anidación de recursos de "un nivel" situación y en otro tiene que manejar una situación de "dos niveles". No estoy seguro de cómo abordar esto.

Una cosa que sí intenté fue no anidar recursos de más de una profundidad, según las instrucciones de Ruby Guides. Los estructuré así:

resources :posts do 
    resources :pictures 
    end 

    resources :fams do 
    resources :pictures 
    resources :kids 
    end 

    resources :kids do 
    resources :pictures 
    end 

Esto causó otro conjunto de problemas con las rutas ya que la relación de familia a hijo ya no se conservaba. Tampoco pude conseguir que polymorphic_path funcione correctamente en todas las diferentes vistas picture.

Así que aquí está mi pregunta principal: ¿Alguien sabe de un ejemplo/tutorial de Rails 3 donde los recursos anidados, pertenece a/has_manía, y las relaciones polimórficas están todos juntos, especialmente donde no es solo el simple, dos- relación de nivel que muestra la mayoría de los ejemplos? (Soy bastante nuevo en Rails y los ejemplos de Rails 2 que he encontrado en estas áreas son confusos dada mi falta de experiencia histórica en Rails.)

¿O alguien puede decirme cómo estructurar las declaraciones link_to EDIT y link_to DELETE para mi picture vistas, así como la instrucción redirect-to para mis métodos create, update y destroy en mi controlador pictures?

Gracias!

Respuesta

7

Su ejemplo de código que limitó su anidación a 2 niveles es bastante cercano a la respuesta. Para evitar rutas duplicadas para fams-> niños y niños, puede usar la opción: only con una matriz en blanco para que los niños de 1er nivel no generen rutas, excepto en el contexto de niños-> imágenes, así:

resources :posts do 
    resources :pictures 
end 

resources :fams do 
    resources :pictures 
    resources :kids 
end 

resources :kids, only: [] do # this will not generate kids routes 
    resources :pictures 
end 

para el código anterior, puede utilizar el siguiente para construir tu edición url polimórfica:

polymorphic_url([fam, picture], action: :edit) # using Ruby 1.9 hash syntax 
polymorphic_url([kid, picture], action: :edit) 
0

No puedo hablar por el problema de asociación polimórfica (probablemente necesite más información sobre el error real) pero de hecho se dirige en la dirección correcta al definir sus recursos anidados solo un nivel de profundidad. Aquí hay un popular article de Jamis Buck que se ha convertido en una referencia y que probablemente deba consultar.

+1

Sí, he leído a través de ese artículo muchas veces. Lo encuentro muy superficial. Va por la simplicidad, pero no aborda cómo mantener las relaciones a través de los múltiples niveles. Agregue polimorfismo con las rutas dinámicas que requiere, y tiene un problema muy complejo que no ha sido bien abordado por nada que haya visto. Estoy al punto de que estoy a punto de eliminar el polimorfismo y comenzar a repetirme construyendo diferentes controladores de imagen para cada uno de mis modelos de datos principales. Mucho para SECO. –

2

He tenido este mismo problema por un tiempo.Tengo que trabajar ahora, pero no es bello: S

De un monstruo anidada como:

http://localhost:3000/destinations/3/accommodations/3/accommodation_facilities/52 

Sus params objeto termina pareciéndose a esto:

action: show 
id: "52" 
destination_id: "3" 
accommodation_id: "3" 
controller: accommodation_facilities 

donde "id" representa el id del modelo actual (último en la cadena) y los otros tienen id_nombre_del_modelo

Para representar correctamente otro enlace anidado en t su página, lo necesario para pasar de una matriz de objetos que componen la ruta completa, por ejemplo, para enlazar a un objeto FacilityType de ficción que tendría que hacer:

<%= link_to "New", new_polymorphic_path([@destination, @accommodation, @accommodation_facility, :accommodation_facility_type]) %> 

Para generar esta matriz del objeto params, yo uso este código en application_helper.rb

def find_parent_models(current_model = nil) 
    parents = Array.new 

    params.each do |name, value| 
     if name =~ /(.+)_id$/ 
     parents.push $1.classify.constantize.find(value) 
     end 
    end 

    parents.push current_model 

    parents 
end 

Luego de hacer automáticamente el mismo enlace, puede hacerlo alegremente:

<%= link_to "New", new_polymorphic_path(find_parent_models(@accommodation_facility).push(:accommodation_facility_type)) %> 

Cualquier punteros en hacer esta solución menos incompletas son muy welcom e:]

+0

¿Qué pasa si un usuario escribe una dirección que termina con: '..facilities/52? User_id = 1 & pathname_id =/etc/passwd & application_controller_id = 1 & xyzzy_id = 1 & file_utils_id = 1 ...' y así sucesivamente? Supongo que tienes un bonito diseño de 500.html. ;-)) – Arsen7

+0

Es una imagen de un gatito. Sin embargo, un punto interesante, ¿pero los rieles no tienen este problema de todos modos? Si intento: localhost: 3000/destinations/1 /? Destination_id = 1 ya está asustado –

+0

Con un parámetro llamado 'xyzzy_id' Rails no lo va a hacer por sí solo. Si un atacante puede encontrar una clase que responda al método 'encontrar', puede hacer cosas realmente desagradables. – Arsen7

Cuestiones relacionadas