Rails: confundido sobre la sintaxis para pasar locales a parciales

99

Entender la "magia" de Rails en lo que respecta a renderizar parciales (y pasar locales a ellos).

¿Por qué funciona esto?

<%= render "rabbits/form" %>

Y este trabajo:

<%= render "rabbits/form", :parent => @warren, :flash => flash %>

pero esto no funciona:

<%= render "rabbits/form", :locals => { :parent => @warren, :flash => flash } %>

Pero esto hace:

<%= render :partial =>"rabbits/form", :locals => { :parent => @warren, :flash => flash } %>

Además, ¿cómo puedo buscar estos matices para no tener que molestar a la gente con SO?

Meltemi
fuente
3
En un comentario a continuación, decía que los documentos de la API de rieles no se pueden buscar tanto. En su lugar, debería probar este sitio: apidock.com/rails . También tiene ruby ​​y rspec allí.
ryeguy

Respuestas:

152

La respuesta corta es que el método de representación mira el primer argumento que pasa. Si pasa un hash (que incluye :partial => 'foo', :locals => {blah blah blah}), pasará todos sus argumentos como un hash y los analizará en consecuencia.

Si pasa una cadena como su primer argumento, se supone que el primer argumento es su nombre parcial y pasará el resto como sus locales. Sin embargo, en esa llamada posterior, en realidad asigna :locals => your_locals_argument, que en este caso es todo :locals => {locals hash}, en lugar de solo {locals hash}; es decir, terminas con :locals => {:locals => {locals hash}}, en lugar de :locals => {locals hash}.

Así que mi consejo es que siempre pase valores explícitamente de la misma manera todo el tiempo, y no tendrá problemas. Para aprender sobre esto, fui directamente al código en sí ( actionpack / lib / base.rb , render()método en Rails 2; Rails 3 es diferente). Es un buen ejercicio.

Además, no se preocupe por "molestar" a la gente en SO. Por eso existe este sitio. Incluso aprendí algo de esto.

Doug R
fuente
5

si necesita especificar: locales, debe especificar: parcial o: plantilla

<%= render :partial => "rabbits/form", :locals => {...} %>

Deberia trabajar

sethvargo
fuente
tiene que ver con la forma en que ruby ​​evalúa el hash si tiene curiosidad de esa manera.
sethvargo
De hecho funciona ... como especifiqué en mi pregunta ... pero lo que me pregunto es ¿por qué? y donde esta documentado? ¿solo mirando la fuente? Y, si esa es la única forma de encontrar y comprender estos innumerables matices en Rails, entonces me pregunto cómo y dónde hacer para localizar e interpretar esto desde la fuente. No puedo simplemente hacer clic en "renderizar" y luego profundizar en la fuente (no con TextMate de todos modos) ¿o sí?
Meltemi
1
ah! así que realmente estás interesado :). Sí, la única forma de averiguar estas cosas es a.) Tener una corazonada como la que tuvo y b.) Ver el código fuente. Sin embargo, no tengo idea de cómo profundizar en la fuente ... lo siento
sethvargo
ok, morderé ... ¿cómo buscas este tipo de cosas? ¿Acabas de cavar a través de tu clone https://github.com/rails/rails.git? ¿O hay un mejor camino? Lo siento, pero soy relativamente nuevo en RoR y aún no he encontrado una forma buena / fácil / consistente de buscar documentación de Rails ... tal que HAY alguna. http://api.rubyonrails.org/no se puede buscar fácilmente . y la fuente de git tampoco es ... suspiro
Meltemi
No soy un experto de ninguna manera, pero uso Aptana Studio. Está construido sobre la misma plataforma que eclipse (si está familiarizado). Te permite "hacer clic" y rastrear como dijiste. También puede hacer una búsqueda en el código y tiene una terminal integrada, etc. Precaución: es un archivo bastante grande
sethvargo
2

Para ser honesto, solo conozco estos casos de uso, porque me he mantenido al día con Rails durante los últimos años y leí los anuncios de que se ha agregado una nueva forma de hacerlo. Yo mismo a menudo cometo un error, pero por lo general se corrige fácilmente.

Es una de esas partes de la API de Rails que no se ha pensado a fondo, si me preguntas. Simplemente acumuló más y más azúcar sintáctico a lo largo de los años, sin menospreciar el comportamiento anterior. El método de render tiene diabetes.

Para empeorar las cosas, el renderizado se comporta de manera diferente en el controlador y en la vista. También miro el contenido del primer argumento para ver si es un archivo, plantilla, acción o parcial. Si comienza con una barra, entonces es un archivo o algo así.

Estoy a favor de utilizar la notación más corta siempre que sea posible. Porque las notaciones cortas comunican la intención bastante bien. Al leerlo, generalmente hace lo que crees que hace. Escribir parciales no es sencillo.

iain
fuente
1

Aquí está la fuente del método de renderizado de http://api.rubyonrails.org/classes/ActionView/Rendering.html#method-i-render :

def render(options = {}, locals = {}, &block)
  case options
  # Here is your last case
  when Hash
    if block_given?
      _render_partial(options.merge(:partial => options.delete(:layout)), &block)
    elsif options.key?(:partial)
      _render_partial(options)
    else
      template = _determine_template(options)
      lookup_context.freeze_formats(template.formats, true)
      _render_template(template, options[:layout], options)
    end
  when :update
    update_page(&block)
  else
    # here the first three cases
    _render_partial(:partial => options, :locals => locals)
  end
end

¡Espero que esto ayude!

Andrea Salicetti
fuente
¡Esto ayuda , gracias! Pero no me ayuda a ayudarme a mí mismo ... si sabes a qué me refiero ...
Meltemi