text_field tag rails form_with form_for form ruby-on-rails ruby-on-rails-3 helper block

ruby on rails - rails - Bucle y salida content_tags dentro de content_tag en helper



rails routes (5)

Estoy probando un método auxiliar que generará una lista de elementos, que se llamará así:

foo_list( [''item_one'', link_to( ''item_two'', ''#'' ) ... ] )

He escrito el ayudante así después de leer Uso de ayudantes en los rieles 3 para generar html :

def foo_list items content_tag :ul do items.collect {|item| content_tag(:li, item)} end end

Sin embargo, solo obtengo un UL vacío en ese caso, si hago esto como una prueba:

def foo_list items content_tag :ul do content_tag(:li, ''foo'') end end

Obtengo el UL & LI como se esperaba.

He intentado cambiarlo un poco haciendo:

def foo_list items contents = items.map {|item| content_tag(:li, item)} content_tag( :ul, contents ) end

En ese caso, obtengo la lista completa, pero las etiquetas LI son html escapadas (aunque las cadenas son HTML seguras). Hacer content_tag(:ul, contents.join("/n").html_safe ) funciona pero me parece mal y creo que content_tag debería funcionar en modo de bloque con una colección de alguna manera.


El gran problema es que content_tag no hace nada inteligente cuando recibe matrices, debe enviar contenido ya procesado. Descubrí que una buena forma de hacerlo es doblar / reducir la matriz para resolverlo todo junto.

Por ejemplo, su primer y tercer ejemplo pueden usar lo siguiente en lugar de su línea items.map/collect:

items.reduce(''''.html_safe) { |x, item| x << content_tag(:li, item) }

Para referencia, aquí está la definición de concat que está ejecutando cuando ejecuta este código (de actionpack / lib / action_view / helpers / tag_helper.rb).

def concat(value) if dirty? || value.html_safe? super(value) else super(ERB::Util.h(value)) end end alias << concat


Junto con las respuestas anteriores, esto me funcionó bien:

(1..14).to_a.each do |age| concat content_tag :li, "#{link_to age, ''#''}".html_safe end


No pude conseguir ese trabajo mejor.

Si ya estuvieras usando HAML , podrías escribir a tu ayudante así:

def foo_list(items) haml_tag :ul do items.each do |item| haml_tag :li, item end end end

Uso desde la vista:

- foo_list(["item_one", link_to("item_two", "#"), ... ])

La salida se pretende correctamente.


Podría usar content_tag_for , que funciona con colecciones:

def foo_list(items) content_tag(:ul) { content_tag_for :li, items } end

Actualización: En Rails 5 content_tag_for (y div_for ) se movieron a una gema separada. Tienes que instalar la gema record_tag_helper para poder usarlos.


Prueba esto:

def foo_list items content_tag :ul do items.collect {|item| concat(content_tag(:li, item))} end end