rails how content_for collection application ruby-on-rails ruby partial actionview

ruby-on-rails - how - render a partial rails



Rieles: ¿deberían los parciales estar al tanto de las variables de instancia? (4)

En versiones recientes de Rails, es bastante más fácil renderizar parciales y pasarles a los locales. En lugar de esto.

<%= render :partial => ''form'', :locals => { :item => @item } %>

Puedes hacerlo.

<%= render ''form'', :item => @item %>

No hago esto en el generador de Nifty Scaffold para mantener la compatibilidad con versiones anteriores, pero lo cambiaré en versiones futuras.

En cuanto a si es aceptable usar variables de instancia en parciales. Creo que es. En todos los aspectos prácticos, ¿cuál es la desventaja? Ciertamente, las cosas pueden salirse de control si no es coherente, pero me gusta aplicar estas pautas.

  1. Nunca crees una variable de instancia solo para compartirla entre parciales. Por lo general, esto significa que solo compartirá el objeto de recurso del controlador.

  2. Si el parcial es el mismo nombre que el recurso, páselo como local con <%= render @item %> .

  3. Si el parcial se va a compartir entre varios controladores, solo use los locales.

Esto es lo que funciona bien para mí de todos modos.

Consejo de bonificación: si se encuentra transfiriendo a muchos locales a un parcial y quiere que algunos de ellos sean opcionales, cree un método auxiliar que represente el parcial. Luego, siga siempre el método de ayuda para que pueda crear una interfaz limpia con args opcionales para representar el parcial.

Nifty_scaffolding de Ryan Bates, por ejemplo, hace esto

edit.html.erb

<%= render :partial => ''form'' %>

new.html.erb

<%= render :partial => ''form'' %>

_form.html.erb

<%= form_for @some_object_defined_in_action %>

Ese estado oculto me hace sentir incómodo, por lo que generalmente me gusta hacer esto

edit.html.erb

<%= render :partial => ''form'', :locals => { :object => @my_object } %>

_form.html.erb

<%= form_for object %>

Entonces, ¿qué es mejor: a) tener parciales que accedan a variables de instancia ob) pasar un parcial a todas las variables que necesita?

He estado optando por b) últimamente, pero me encontré con un pequeño pepinillo:

some_action.html.erb

<% @dad.sons.each do |a_son| %> <%= render :partial => ''partial'', :locals => { :son => a_son } %> <% end %>

_partial.html.erb

The son''s name is <%= son.name %> The dad''s name is <%= son.dad.name %>

son.dad hace una llamada a la base de datos para buscar al padre! Así que tendría que acceder a @dad, que sería volver a a) tener parciales acceder a variables de instancia o tendría que pasar @dad en locales, cambiando el procesamiento: parcial a <% = render: parcial => ''parcial'' ,: locals => {: dad => @dad,: son => a_son}%>, y por alguna razón pasar varios Vars a mi parcial me hace sentir incómodo. Quizás otros se sientan de esta manera también.

Espero que tenga algo de sentido. Buscando una idea de todo esto ... ¡Gracias!


Yo voto por a) por una razón muy específica: ¡SECO! Si comienzas a pasar una variable como esa, lo próximo que sabes es que es un desastre, digamos que necesitas cambiar la forma en que se nombra a tu variable u otra cosa al respecto, entonces debes ir a TODAS tus vistas y cambiarlas en lugar de UNO parcial. Además, si cambias tu parcialidad, digamos que produce una tabla con algún resultado, cambiará en todas tus vistas, por lo que necesitarás saber qué vistas se usan, un IDE apropiado debería poder ayudarte con eso, pero también me gusta tener una pequeña sección de comentarios en la parte superior de la vista, donde menciono dónde se usa y por qué, ayuda a otro programador y le ayuda a recordar en caso de que necesite volver a un parcial y modificarlo. Pero el objetivo de este parcial es llamarlo SIN tener que pasar nada desde la vista, para que no tenga que modificar todos los lugares desde donde se llama a partial si esa variable cambia de algún modo.

En definitiva, esta es una opción de diseño, y para ser honesto, a menos que esté ejecutando un facebook, la búsqueda adicional que hace no es tan importante, pero no es muy SECA.

PD: Solo lo pensé, puedes abstraer la forma en que llamas parcial en un método de ayuda, entonces si la forma en que llamas a tu parcial necesita cambiar, entonces solo necesitas modificar un lugar.


Puedes tenerlo en ambos sentidos. En la parte superior de tu parcial:

<% item ||= @item %>

De esta forma, funciona con o sin pasar la variable local, proporcionando un valor de defecto en el modo, pero no inhibiendo el uso alternativo del parcial.


Usar @instance_variables en parciales es un mal diseño.

Usar la variable de instancia en los parciales funciona, pero puede dificultar el mantenimiento de las aplicaciones si alguna vez se necesitan cambios.

La desventaja de utilizar variables de instancia en parciales es que crea una dependencia en el parcial a algo fuera del alcance del parche (acoplamiento). Esto hace que el parche sea más difícil de reutilizar y puede forzar cambios en varias partes de la aplicación cuando desea realizar un cambio en una parte.

Parciales que usan variables de instancia:

  • debe cambiar cuando la variable de instancia en cualquier controlador que utiliza el parcial cambia el nombre de la variable de instancia o su tipo o estructura de datos
  • provoque que todas las acciones del controlador que utilizan el parcial cambien de la misma manera al mismo tiempo cuando hay cambios en la forma en que se usa la variable de instancia
  • desaconseja la reutilización, ya que solo pueden reutilizarse fácilmente en acciones que configuran variables de instancia con el mismo nombre y datos

En su lugar, pase a los locales a los parciales:

<%= render ''reusable_partial'', :item => @item %>

Ahora, como el item referencias solo parcial y no @item , la acción que representa la vista que representa el reusable_partial puede cambiarse libremente sin afectar el reusable_partial y las otras acciones / vistas que lo generan:

<%= render ''reusable_partial'', :item => @other_object.item %>

Además, esto se puede reutilizar en contextos donde no hay @item:

<%= render ''reusable_partial'', :item => @duck %>

Si mi @duck cambia en el futuro y ya no se graban como lo espera reutilizable_partial (la interfaz del objeto cambia), también puedo usar un adaptador para pasar el tipo de elemento que reusable_partial espera:

<%= render ''reusable_partial'', :item => itemlike_duck(@duck) %>

¿Siempre?

Hay muchas situaciones en las que probablemente no necesite parciales desacoplados como este, y es más fácil a corto plazo usar una variable de instancia. Sin embargo, es difícil predecir las necesidades futuras de su aplicación.

Como tal, esto constituye una buena práctica general a la vez que tiene un costo relativamente bajo.