2009-10-12 16 views
6

Estoy desarrollando un sitio web de Rails 2.3.1. A lo largo del sitio web, necesito tener un formulario para crear publicaciones en varias páginas (página de inicio, página Crear publicaciones, página de publicación de publicaciones, página de lista de comentarios, etc.) baste decir que este formulario debe estar en muchas páginas servidas por una variedad de controladores). Cada una de estas páginas muestra una gran variedad de otra información que se recupera en el controlador/acción correspondiente. Por ejemplo, la página de inicio enumera las últimas 10 publicaciones, contenido extraído del DB, etc.La mejor práctica de Rails para tener el mismo formulario en varias páginas

Por lo tanto, he movido el formulario de creación de publicaciones a su propio parcial, e incluí este parcial en todas las páginas necesarias. Tenga en cuenta que el formulario en los POST Parciales a/preguntas (que se dirige a PostsController :: create - esto es el comportamiento predeterminado de los rieles).

El problema al que me estoy enfrentando es cuando el formulario Posts no se completa correctamente, de forma predeterminada el método PostsController :: create hace las preguntas/new.html.erb, incluso si el formulario se envió desde la página de inicio (/ home/index.html.erb).

He intentado cambiar el formulario en el parcial para enviar el "submitting_controller" y "submitting_action", y en PostsController :: create, when @ post.save? == falso, represento action => "../submitting_controller/submitting_action" (Lo cual es un poco hacky, pero te permite renderizar acciones de sitios que no sean de PostsController).

Esto parecía funcionar bien en la superficie. El formulario incompleto fue presentado en la vista que lo envió con todos los mensajes @ post.errors correctos, etc. El problema fue que TODO el resto de los datos en las páginas no aparecieron, porque los métodos actuales submitting_controller/submitting_action no fueron llamados, solo la vista asociada. (Recuerde, hice un render que conserva objetos de instancia, en lugar de un redirect_to que no conserva el objeto de instancia @post que tiene todos los mensajes de error y valores enviados.)

Por lo que puedo ver, tengo dos opciones :

1) Puedo almacenar el objeto @post en la sesión cuando @ post.save? falla en PostsController :: create, redirect_to submitting_controller/submitting_action, en cuyo punto saco el objeto @post de la sesión y lo uso para volver a llenar los mensajes de formulario/error. (Por lo que entiendo, el almacenamiento de objetos en la sesión es MALO la práctica en los rieles)

2) Puedo mover toda la lógica utilizada para extraer los datos del formulario de creación no post de los diversos submitting_controller/submitting_action, ponerlo en el ApplicationController, crea una declaración de conmutación gigante en PostsController :: create para submitting_controller/submitting_action y llama a los métodos en ApplicationController para obtener todos los datos adicionales necesarios para el procesamiento de cada página de envío.

¿Piensas en la mejor manera de hacer esto dentro de Rails?

Respuesta

1

Por casualidad, ¿su modelo de publicación está en una relación belongs_to con cada modelo de controlador que utilizará para presentar su formulario? ¿Está haciendo algún procesamiento especial en el controlador Post más allá de Post.create(params[:post])?

Si contestó que sí a la primera pregunta y no a la segunda, podría terminar con un cambio mínimo agregando accept_nested_attributes_for a cada uno de los controladores en los que un usuario puede crear una publicación.

Independientemente, Robertpostill tiene razón en que esto es probablemente cuando empiece a buscar AJAX, simplemente reemplace la sección de la página. El único problema es qué hacer si un usuario tiene JavaScript desactivado. Personalmente, me gusta diseñar para el caso que no es javascript y agregar métodos de conveniencia.

En cuanto a los pensamientos sobre lo que se tiene en cuenta sus dos opciones,

1) He utilizado este método para almacenar una copia superficial de un objeto en el hash flash. Preservarlo a través de redirecciones. Sin embargo, esto podría no funcionar para usted dada la naturaleza variable de las publicaciones. Como solo puede enviar aproximadamente 4K de datos, y eso incluye otra información además de su copia superficial.

2) Véase la respuesta de robertpostill

+0

Emfi, Buen punto acerca de los atributos anidados. Eso no se me había ocurrido. También es importante el punto que hace sobre el incumplimiento de JS. La sensación que tengo es que el que pregunta (a falta de un mejor manejo :) acabará perjudicando el rendimiento de la aplicación a través de la cantidad de acción DB que necesitaría para realizar la reconstitución de todos los objetos. – robertpostill

+0

En esto estamos de acuerdo. Sin embargo, la diferencia entre no-javascript y AJAX suele ser una llamada link_to_remote, un RJS que representa una plantilla, y posiblemente una pequeña lógica de controlador para evitar las llamadas a la base de datos que normalmente haría. – EmFi

+0

EmFi, Desafortunadamente, el modelo de publicación y los modelos cuyo controlador usará para representar el formulario pueden no estar relacionados. (HomeController no tiene un modelo de respaldo, incluso). Hago algunas comprobaciones en un mecanismo de captcha en PostController :: create (el campo captcha no es parte del Post Model, sino más bien de su propio módulo). Creo que tanto usted como Robertpostill tienen razón en AJAX es la forma de abordar este problema.Solo tengo que descubrir cómo hacerlo con jQuery (opté por no usar Prototype, personal pref) y no arruinar nada en Rails. – empire29

1

Este es el punto que pasa de las actualizaciones de página completa a las secciones de actualización de una página mediante el uso de AJAX. Hay un montón de cosas que debería considerar, pero el enfoque más realista sería dividir la respuesta entre una respuesta AJAX y una respuesta HTML simple. Consulte this ONLamp article, this register article o the awesome agile web development with rails book. Esencialmente, su controlador representa un nuevo div que reemplaza el antiguo div que contiene el resultado de enviar el parcial.

En su pregunta se mencionan dos enfoques y así voy a tratar de darle algunas sugerencias sobre cómo y por qué no aquí:

Opción 1) Ths opción no es tan malo con un par de ajustes. El principal truco es almacenar el objeto en forma serializada en el DB. Luego simplemente pase la identificación del objeto serializado.Tus ventajas son que los datos de la sesión se mantienen, por lo que la recuperación de una sesión es más ordenada y tu sesión se mantiene ligera. La desventaja de esto es que tener un cubo de fracciones de sesión en tu base de datos contaminará tu aplicación y tendrás que pensar en cómo expirar el fragmento de sesión no utilizado de la base de datos. Nunca he visto bien este final ...

Opción2) ¡Eeek no está dentro del controlador de la aplicación! :) En serio, mantenlo como tu arma de último recurso. Sin embargo, puede mostrar cosas en los ayudantes y obtener acceso a esos métodos dentro de sus controladores y vistas. Sin embargo, la prueba de esas cosas no es tan fácil, así que ten cuidado antes de elegir esa ruta. Las sentencias de cambio se pueden reemplazar en las aplicaciones de OO con un poco de pensamiento, sin duda en su caso puede usar hash de opciones para obtener una forma rápida de tener algo de inteligencia sobre el estado de la aplicación en el momento en que se realiza la solicitud.

+0

Gracias, Un par de pensamientos: Opción 1) objs Seguimiento en el PP suena como que podría convertirse en una pesadilla, una pendiente resbaladizo. Opción 2) No creo que los controladores puedan acceder a los ayudantes (debe ser influencia de CakePHP). Acepto que ApplicationController es un lugar difícil para ponerlos;) The Hash es una buena idea, aunque todavía no me gusta que toda esta selección de datos específica de la vista se convierta en ayudantes, parece que podría fácilmente convertirse en una pesadilla de mantenimiento. Leeré los artículos que me proporcionó, pero creo que AJAX será el camino a seguir. – empire29

Cuestiones relacionadas