29

Je fais de mon mieux pour construire un assistant qui génère un < 'ul> composé de tous les membres d'une collection. Pour chaque membre de la collection je veux imprimer un < 'li> qui a un titre, et une div de liens vers le membre CRUD. C'est assez similaire à ce que Rails produit pour l'échafaudage pour la vue d'index.Utilisation d'aides dans les rails 3 pour la sortie html

Voici l'aide que j'ai:

def display_all(collection_sym) 
    collection = collection_sym.to_s.capitalize.singularize.constantize.all 

    name = collection_sym.to_s.downcase 

    html = '' 

    html << "<ul class=\"#{name}-list\">" 

    for member in collection do 
    html << content_tag(:li, :id => member.title.gsub(' ', '-').downcase.strip) do 
    concat content_tag(:h1, member.title, :class => "#{name}-title") 
    concat link_to 'Edit', "/#{name}/#{member.id}/edit" 
    concat "\|" 
    concat link_to 'View', "/#{name}/#{member.id}" 
    concat "\|" 
    concat button_to 'Delete', "/#{name}/#{member.id}", :confirm => 'Are you sure? This cannot be undone.', :method => :delete 
    end 
    end 

    html << '</ul>' 

return html 
end 

Et cette sortie exactement ce que je veux. Tout d'abord, si quelqu'un pense qu'il y a une meilleure façon de faire cela, n'hésitez pas à me corriger, je suppose que je fais ça à la basse, mais pour le moment c'est la seule façon dont je sais comment.

Je puis tenté d'envelopper les liens dans un div comme suit:

def display_all(collection_sym) 
    collection = collection_sym.to_s.capitalize.singularize.constantize.all 

    name = collection_sym.to_s.downcase 

    html = '' 

    html << "<ul class=\"#{name}-list\">" 

    for member in collection do 
    html << content_tag(:li, :id => member.title.gsub(' ', '-').downcase.strip) do 
    concat content_tag(:h1, member.title, :class => "#{name}-title") 
    concat content_tag(:div, :class => "links-bar") do 
     concat link_to 'Edit', "/#{name}/#{member.id}/edit" 
     concat "\|" 
     concat link_to 'View', "/#{name}/#{member.id}" 
     concat "\|" 
     concat button_to 'Delete', "/#{name}/#{member.id}", :confirm => 'Are you sure? This cannot be undone.', :method => :delete 
    end 
    end 
end 

html << '</ul>' 

return html 
end 

Cependant, maintenant je ne reçoivent plus aucun des balises dans la sortie div.links-bar à la vue. Je suis sûr que cela doit avoir quelque chose à voir avec le bloc et les reliures, mais je peux, pour la vie de moi, comprendre ce qu'il faut faire ou comment y remédier. Quelqu'un peut-il offrir de l'aide?

+3

Qu'est-ce que Votre première intention est-elle d'utiliser des aides? Pourquoi ne pas le faire dans le modèle à la place? –

+0

Hmmmm, je suppose que je pourrais utiliser un modèle, je ne sais pas pourquoi je n'ai pas pensé à ça. – TheDelChop

+1

partials est la voie à suivre sur ce que je pense ... kudos pour labourer à travers tout ce code ... eu mal à la tête juste de le lire ;-) – Ryan

Répondre

44

Je suis d'accord avec le commentaire ci-dessus recommandant l'utilisation d'une partie ... mais si vous en avait vraiment besoin de le faire dans une aide, c'est un moyen de mettre en œuvre plus propre:

def display_all(collection) 
    content_tag(:ul, class: "list") do 
    collection.collect do |member| 
     concat(content_tag(:li, id: member.name.gsub(' ', '-').downcase.strip) do 
     member.name 
     end) 
    end 
    end 
end 

Je passe dans une collection explicitement plutôt que de passer un symbole pour créer une collection, donc vous n'êtes pas toujours obligé d'afficher TOUS les enregistrements d'une table particulière à la fois. Vous pouvez ajouter la pagination, etc.

+0

Oui, je suis d'accord que si je devais le faire de cette façon, c'est la meilleure façon de le faire.Mais comme les autres mecs l'ont dit, je vais utiliser un partiel à la place.Merci! – TheDelChop

+4

N'avez-vous pas besoin d'une concaténation pour l'intérieur content_tag? –

24

@ Joe, Vous pouvez toujours utiliser votre méthode display_all(collection_sym) utiliser Just: return html.html_safe au lieu de: return html

Je trouve toujours que dans de nombreuses situations, il est mieux pour générer du HTML à partir d'aides, au lieu d'utiliser des partiels. Donc, la fonction html_safe dans Rails 3 s'assurera que vous générez du HTML, au lieu de le convertir en String.

+0

Travaillé comme un charme pour moi, et est gentil et simple quand j'ai juste besoin de générer une étiquette ou deux à partir de l'assistant. –

2

Comme le dit @TheDelChop, vous avez besoin d'un concat pour la content_tag intérieure, sinon la sortie est juste <ul></ul>

Voici ce qui ressemble à:

def display_all(collection) 
    content_tag(:ul, :class => "list") do 
    collection.collect do |member| 
     concat(
     content_tag(:li, :id => member.name.gsub(' ', '-').downcase.strip) do 
      member.name 
     end 
    ) 
    end 
    end 
end 

Plus explication ici: Nesting content_tag in Rails 3