开发者

nested content_tag designing table

I'm stuck...

I'm trying to create a table helper in my application helper like this:

def simple_grid(theGrid, theData)
    content_tag :div, :class => "text_area_show" do
      content_tag :table, :width => "95%" do
        concat content_tag :tr, "" do
          theGrid['fields'].each do |field|
            开发者_JAVA百科concat content_tag(:th, field)
          end
        end
        theData.collect do |record|
          concat content_tag :tr do
            theGrid['fields'].collect do |field|
              concat content_tag(:td, record[field], :align => "center")
            end
          theGrid['right_links'].collect do |right_link,path|
            case right_link
            when 'show'
              concat content_tag(:td, link_to(right_link, "#{path}#{record.id}"), :align => "center")
            when 'edit'
              concat content_tag(:td, link_to(right_link, "#{path}#{record.id}/edit"), :align => "center")
            end
          end
        end
      end
    end
  end
  end

with this in my controller:

  @users = User.all
    @grid = {'fields' => ['firstname','lastname','email'],
             'right_links' => {'show' => '/admin/users/', 'edit' => '/admin/users/'}
    }

And this in my view:

<%= simple_grid(@grid, @users) %>

This generates the following html:

<div class="text_area_show"><table width="95%"><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr></table></div>

I miss all my td tags.

Any help to tell my what's wrong would be highly appreciated!

Nicolas.


This is what I did first but, as a newbie to Rails, I'm trying to think the Rails way...

The best solution I found until now is:

  def simple_grid(theGrid, theData)
    content_tag :div, :class => "text_area_show" do
      concat(content_tag(:table, :width => "95%") do
         concat(content_tag(:tr) do
          theGrid['fields'].collect do |field|
            concat(content_tag(:th, field))
          end
        end)
        theData.collect do |record|
          concat(content_tag(:tr) do
            theGrid['fields'].collect do |field|
              concat(content_tag(:td, record[field], :align => "center"))
            end
            theGrid['right_links'].collect do |right_link,path|
              case right_link
              when 'show'
                concat(content_tag(:td, link_to(right_link, "#{path}#{record.id}"), :align => "center"))
              when 'edit'
                concat(content_tag(:td, link_to(right_link, "#{path}#{record.id}/edit"), :align => "center"))
              end
            end
          end)
        end
      end)
    end
  end

It is pretty ugly but it works. Any suggestion to do better work is welcome!


content_tag is only suitable for simple helpers. For complex helpers it's far better to use a partial :

 def simple_grid( grid, data )
   render partial: '/shared/simple_grid', locals: { grid: grid, data: data }
 end

so you can take advantage of your favourite template engine. Notice that i usually store such partials in a 'shared' folder in 'app/views', but it's up to you. The helper in this case is not even mandatory, but it can be useful at times when you need to process data before rendering.

Another approach would be the decorator pattern (using the Draper gem), but it's another topic.


Had a nightmare of a time trying to resolve your issue because of the multiple content_for tags. Read in the API docs that you need to always use .collect instead of .each and that for multiple content_for tags within a block you need to use concat... but try as I might, I can't get it work either..

Last resort you could always fall back to:

@output = "<div class='text_area_show'>
    <table width='95%'>
      <tr>"
theGrid['fields'].each { |field| @output += "<th>#{field}</th>"}
@output += "</tr>"

theData.collect do |record|
   @output += "<tr>"
      theGrid['fields'].each { |field| @output += "<td align='center'>#{record[field]}</td>"}

      theGrid['right_links'].collect do |right_link,path|
        case right_link
        when 'show'
          @output += "<td align='center'>#{link_to(right_link, "#{path}#{record.id}")}</td>"
        when 'edit'
          @output += "<td align='center'>#{link_to(right_link, "#{path}#{record.id}/edit")}</td>"
        end
      end
   @output += "</tr>"
end

@output += "</table></div>"
@output
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜