web-dev-qa-db-ja.com

Rails 3でヘルパーを使用してHTMLを出力する

コレクションのすべてのメンバーで構成される<'ul>を出力するヘルパーを作成するために最善を尽くしています。コレクションの各メンバーについて、タイトルと、メンバーをCRUDするためのリンクのdivを持つ<'li>を出力します。これは、インデックスビューのスキャフォールディングの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出力内のマークアップをビューに取得できなくなりました。これはブロックとバインディングに関係しているに違いないと思いますが、私の人生の中で、何をどのように修正するかを理解することができます。誰か助けを提供できますか?

29
TheDelChop

パーシャルの使用を推奨する上記のコメントに同意します...しかし、DIDヘルパーでこれを行う必要がある場合、これは実装するためのよりクリーンな方法です。

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

シンボルを渡してコレクションを作成するのではなく、明示的にコレクションを渡して、特定のテーブル内のすべてのレコードを一度に表示する必要がない場合があります。ページネーションなどを追加できます。

46
Dave Pirotte

@ Joe、メソッドを使用できますdisplay_all(collection_sym)使用するだけ:return html.html_safe の代わりに: return html

私はまだ多くの状況で、パーシャルを使用するよりもヘルパーからHTMLを生成する方が良いことに気づきます。したがって、html_safeRailsの関数は、HTMLをStringに変換する代わりに、HTMLを確実に生成します。

24
Linh Chau

@TheDelChopが言うように、内部content_tagにはconcatが必要です。それ以外の場合、出力は<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

ここでさらに説明: Railsにcontent_tagをネストする

2
James Hibbard