web-dev-qa-db-fra.com

Utilisation des assistants dans Rails 3 pour sortir du html

J'essaie de mon mieux de créer une aide 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 CRUD le membre. Ceci est assez similaire à ce que Rails sort pour l'échafaudage pour la vue d'index.

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 le faire, n'hésitez pas à me corriger, je soupçonne que je fais cela de manière basse, mais pour le moment c'est la seule façon dont je sais comment.

J'ai ensuite tenté d'encapsuler les liens dans une 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, je n'obtiens plus aucun balisage à l'intérieur de la sortie div.links-bar vers la vue. Je suis sûr que cela doit avoir quelque chose à voir avec le bloc et les fixations, mais je peux pour la vie de moi comprendre quoi ou comment procéder pour le réparer. Quelqu'un peut-il offrir de l'aide?

29
TheDelChop

Je suis d'accord avec le commentaire ci-dessus recommandant l'utilisation d'un partiel ... mais si vous DID devez le faire dans une aide, c'est une façon plus propre de mettre en œuvre:

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 transmettrais une collection de manière explicite plutôt que de passer un symbole pour créer une collection de sorte que vous n'êtes pas toujours obligé d'afficher TOUS les enregistrements d'une table particulière à la fois. Vous pouvez ajouter la pagination, etc.

46
Dave Pirotte

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

Je trouve toujours que dans de nombreuses situations, il est préférable de générer du HTML à partir des assistants, plutôt que d'utiliser des partiels. Alors le html_safe fonction dans Rails s'assurera que vous générez du HTML, au lieu de le convertir en String.

24
Linh Chau

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

Voici à quoi cela 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 d'explications ici: Imbrication de content_tag dans Rails

2
James Hibbard