Использование помощников в рельсах 3 для вывода HTML - PullRequest
29 голосов
/ 25 августа 2010

Я стараюсь изо всех сил создать помощника, который выводит <'ul>, состоящий из всех членов коллекции. Для каждого члена коллекции я хочу распечатать <'li>, у которого есть заголовок и div с ссылками на CRUD участника. Это очень похоже на то, что Rails выводит для скаффолдинга для представления индекса.

Вот мой помощник:

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 

И этот вывод именно то, что я хочу. Прежде всего, если кто-то думает, что есть лучший способ сделать это, пожалуйста, не стесняйтесь поправлять меня, я подозреваю, что я делаю это басовым способом, но на данный момент это единственный способ, которым я знаю как.

Затем я попытался обернуть ссылки в div следующим образом:

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 

Однако теперь я больше не получаю никакой разметки внутри вывода div.links-bar для представления. Я уверен, что это должно быть как-то связано с блокировкой и привязками, но я могу на всю жизнь понять, что или как исправить. Кто-нибудь может предложить какую-либо помощь?

Ответы [ 3 ]

46 голосов
/ 04 сентября 2010

Я согласен с приведенным выше комментарием, рекомендующим использовать частичное ... но если вам ДЕЙСТВИТЕЛЬНО нужно было сделать это в качестве помощника, это более чистый способ реализации:

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

Я бы передал коллекцию явно, вместо того, чтобы передавать символ для создания коллекции, поэтому вам не всегда нужно отображать ВСЕ записи в определенной таблице одновременно. Вы можете добавить нумерацию страниц и т. Д.

24 голосов
/ 12 марта 2011

@ Джо , Вы все еще можете использовать свой метод display_all(collection_sym) Просто используйте: return html.html_safe вместо: return html

Я все еще нахожу, что во многих ситуациях лучше генерировать HTML из помощников, а не использовать партиалы. Таким образом, функция html_safe в Rails 3 гарантирует, что вы генерируете HTML, а не конвертируете его в String.

2 голосов
/ 10 декабря 2015

Как говорит @TheDelChop, вам нужно concat для внутреннего content_tag, в противном случае вывод просто <ul></ul>

Вот как это выглядит:

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

Более подробное объяснение здесь: Вложение content_tag в Rails 3

...