2008-10-23 15 views
29

Inicié recientemente un proyecto de Rails y decidí usar controladores RESTful. Creé controladores para mis entidades clave (como Country) y agregué index, new, edit, create, show, update y delete. Agregué mi map.resources :country a mi archivo de rutas y la vida fue buena.¿Por qué tengo que trabajar más para hacer que mi aplicación Rails se ajuste a una arquitectura RESTful?

Después de que el desarrollo progresó un poco, empecé a tener problemas. A veces necesitaba acciones adicionales en mi controlador. Primero fue la acción search que devolvió las opciones para mi elegante cuadro de búsqueda de autocompletado. Luego vino la necesidad de mostrar los países de dos maneras diferentes en diferentes lugares de la aplicación (los datos mostrados también eran diferentes, por lo que no eran solo dos vistas) - Agregué la acción index_full. Luego, quería mostrar un país por nombre en la URL, no por identificación, así que agregué la acción show_by_name.

¿Qué haces cuando se necesita acciones más allá de la norma index, new, edit, create, show, update, delete en un controlador de REST en Rails? ¿Debo agregar (y mantener) las rutas manuales en el archivo routes.rb (que es un problema), van en un controlador diferente, me vuelvo inseguro o me falta algo fundamental?

Supongo que estoy preguntando, ¿tengo que trabajar más y agregar acciones en mi archivo routes.rb por el privilegio de ser RESTful? Si no estuviera usando map.resources para agregar los objetos de REST, las rutas estándar :controller/:action, :controller/:action/:id manejarían prácticamente todo automáticamente.

+2

Parece haber mucha confusión sobre el significado de REST debido a los métodos predeterminados de los rieles. REST no se limita a esos métodos, y realmente no se trata de esos métodos en particular. Tampoco entiendo por qué sientes que tienes que trabajar más duro al agregar métodos adicionales a un controlador. – jshen

Respuesta

8

Si voy más allá de las acciones estándar de CRUD con mis modelos, normalmente solo agrego los métodos necesarios. La búsqueda es algo que añadir a varios controladores, pero no cada uno, así que agregarlo y mantener las vías normalmente:

map.resources :events, :collection => { :search => :get } 

Moving estas acciones a un controlador totalmente independiente podría mantener algunos de sus controladores REST, pero me parece que mantenerlos en contexto es mucho más útil.

+0

Odio tener que agregar y mantener muchos nombres de acciones en mi archivo de rutas manualmente. Si no estuviera usando REST, entonces no necesitaría hacerlo. ¿Hay una manera más limpia? Si no, entonces este es. – RichH

+1

¿De qué otra manera no necesitarías manejar las ediciones de ruta? Simplemente usando la sintaxis ": controller => XXX,: action => YYY"? Las rutas con nombre son una buena práctica, ya sea que esté utilizando REST o no. – Micah

+3

Buscar, index_full, show_by_name son todas acciones de recuperación parametrizadas (es decir, la R en CRUD). No hay necesidad de agregar nuevas rutas. –

5

REST no especifica que no pueda tener vistas adicionales. Ninguna aplicación del mundo real podrá usar solo las acciones provistas; esta es la razón por la que puede agregar sus propias acciones.

REST consiste en poder hacer llamadas sin estado al servidor. Su acción de búsqueda no tiene estado cada vez que los datos hasta el momento se devuelven, ¿correcto? Su acción de visualización alternativa también es sin estado, solo una vista diferente.

En cuanto a si deben ser rutas manuales o un nuevo controlador, eso depende de cuán distinta sea la actividad. Su vista alternativa, si proporciona un conjunto completo de operaciones CRUD (crear, leer, actualizar, eliminar) haría bien en estar en un nuevo controlador. Si solo tiene una vista alternativa a los datos, solo agregaría una acción de vista alternativa.

En otras palabras, no parece que su aplicación no sea RESTful, es más una cuestión de darse cuenta de que el conjunto de características generado automáticamente es un punto de partida, no una conclusión.

+0

Estoy informado, así que estoy usando REST correctamente. Creo que mi preocupación es que porque he decidido ser RESTful ahora necesito hacer mucho más trabajo en mi archivo routes.rb que no necesitaría hacer si no usara REST. – RichH

+0

Bueno, el código tiene que ir a alguna parte: tengo curiosidad si siente que tener acciones claramente definidas es menos útil que tener datos de bandera adicionales que digan qué vista usar. Si bien la bandera es fácil de codificar, oscurece un poco lo que hace la acción. La naturaleza reconocible de las acciones es buena. – Godeke

+0

Estoy 100% en contra de la idea de la bandera, no te preocupes. El problema es que una vez que agrego la línea map.resources para que el controlador agregue las asignaciones de REST, mis acciones pasan de ser detectables automáticamente a necesitar ser configuradas manualmente en el archivo de rutas. Entonces empiezo a tener flashbacks de Struts !! – RichH

13

Me gustaría tratar search como un caso especial de index. Ambas acciones devuelven una colección de recursos. Los parámetros de solicitud deben especificar cosas como página, límite, orden de clasificación y consulta de búsqueda.

Por ejemplo:

/resources/index # normal index 
/resources/index?query=foo # search for 'foo' 

Y en resources_controller:

before_filter :do_some_preprocessing_on_parameters 

def index 
    @resources = Resource.find_by_param(@preprocessed_params) 
end 

En cuanto a index_full y search_by_name, lo podría hacer en la división de su controlador actual en dos. Hay un olor a lo que has descrito.

Habiendo dicho eso, tiene toda la razón en que no tiene sentido forzar a su aplicación a rutas de descanso del usuario cuando no entrega nada más de /:controller/:action/:id. Para tomar una decisión, observe la frecuencia con la que está utilizando los ayudantes relajantes de la ruta de recursos en formularios y enlaces. Si no los estás usando, no me molestaría con eso.

+0

El enfoque que describes al principio rompe el patrón MVC en mi mente. Pasé de tener una acción que hace una cosa limpiamente a una acción que hace muchas cosas diferentes de forma oculta. Su último punto es interesante: ¿quizás no debería usar rutas tranquilas? – RichH

+0

Lo veo de esta manera: una búsqueda encuentra un montón de recursos y los muestra en algún tipo de orden. La acción de índice hace lo mismo, pero, de forma predeterminada, de forma codificada. Entonces, en realidad, el índice es un caso especial de búsqueda :) –

+0

Estoy de acuerdo con EmbiggensTheMind: veo el índice como un caso especial de búsqueda. – MiniQuark

-1

Para permanecer RESTANTE en su diseño, debe reconsiderar lo que llama un recurso.

En su ejemplo, una acción de mostrar para un controlador de búsqueda, (recurso de búsqueda) es la dirección para permanecer tranquilo.

En la mía, tengo un controlador salpicadero (mostrar) y los controladores para los campos individuales de ecditors (mostrar y actualizar) en el lugar

+0

No estoy seguro de entender lo que quieres decir. ¿Podría ser más específico? ¿Estás diciendo que algunas acciones (como la búsqueda) deberían verse como recursos? Algo como "map.resources: user_search"? – MiniQuark

0

En mi opinión pueden haber ido un poco fuera de los carriles aquí. ¿Qué pasó con DRY?

Acabo de regresar a Rails sin haber hecho mucho desarrollo con él desde beta y todavía estoy esperando que la bombilla se encienda aquí. Todavía estoy dando una oportunidad, pero si no me ha sucedido al final de mi proyecto actual, probablemente solo me regrese a las rutas estándar anteriores y defina los métodos, ya que realmente los necesito para el próximo. .

+0

Las rutas de recursos tienen poco efecto sobre DRYness, se trata más de convención que de configuración. Establecieron rutas con nombre estándar para todas las acciones de CRUD, que para las aproximadamente 20 aplicaciones de Rails en las que he trabajado siempre han sido más del 90% de las rutas. Por supuesto, utilizando el valor predeterminado: controller /: action /: id parece escueto, pero qué tan SECO es cuando tienes miles y miles de url_for: controller => 'foo',: action => 'bar',: id => @ foo lleno de sus plantillas en lugar de foo_url (@foo)? – gtd

0

No voy a explicar más sobre REST ya que creo que ha sido respondido en esta pregunta, sin embargo, hablaré un poco sobre la ruta predeterminada.

Mi problema principal con la ruta predeterminada es que si tiene varios sitios que usan la misma aplicación de Rails, puede verse horrible.

Por ejemplo, puede haber controladores que usted no quiere que la gente sea capaz de ver en una sola aplicación:

http://example1.somesite.com/example_2/foo/bar/1 

comparar esto a

/:controller/:action/:id 

Esto iría al controlador Ejemplo_2/foo, barra de acción e id 1

Considero que esta es la falla principal de la ruta predeterminada de Rails y esto es algo que las rutas RESTful (con extensiones de subdominios) o solo las rutas con nombre (map.connect 'foo' ...) puede arreglarlo.

Cuestiones relacionadas