rails, как построить таблицу в хелпере используя content_tag? - PullRequest
18 голосов
/ 05 октября 2010

Я определил функцию в помощнике приложения:

def display_standard_table(columns, collection = {})    
  content_tag :table do      
    concat content_tag :thead do
      content_tag :tr do
        concat columns.collect { |column| content_tag(:td, column[:display_name]) }
      end
    end      

    concat content_tag :tbody do
      collection.collect { |elem| 
        concat content_tag(:tr, columns.collect { |column|
          content_tag(:td, elem.attributes[column[:name]])
      })
    }
    end
  end
end

и я называю это на мой взгляд:

<%= display_standard_table(
          [
            { :name => 'id', :display_name => 'Id' },
            { :name => 'login', :display_name => 'Login' },
            { :name => 'first_name', :display_name => 'Name' },
            { :name => 'last_name', :display_name => 'LastName' },
            { :name => 'email', :display_name => 'Email'}
          ], @users) %>

Вывод в html:

<table><thead></thead><tbody></tbody></table>

и должно быть:

<table><thead><tr><td>Id</td><td>Login</td>...</tr></thead><tbody><tr>row here</tr></tbody></table>

и я не могу понять, чего не хватает. (кстати. Я использую rails3)

[EDIT]

def display_standard_table(columns, collection = {})    
  content_tag(:table) do
    concat(content_tag(:thead) do
      concat(content_tag(:tr) do
        concat(columns.collect { |column| content_tag(:td, column[:display_name]) })
      end)
    end)

    concat(content_tag(:tbody) do
      concat(collection.collect { |elem|
        content_tag(:tr, columns.collect { |column|
          content_tag(:td, elem.attributes[column[:name]])
        })
      })
    end)
  end
end

Приведенная выше версия работает нормально, но сгенерированный html экранирован: / в соответствии со строкой документации, созданной content_tag, должен быть html_safe, но они экранированы: /

Ответы [ 5 ]

32 голосов
/ 14 июля 2012
def display_standard_table(columns, collection = {})

 thead = content_tag :thead do
   content_tag :tr do
    columns.collect {|column|  concat content_tag(:th,column[:display_name])}.join().html_safe
   end
 end

 tbody = content_tag :tbody do
  collection.collect { |elem|
    content_tag :tr do
      columns.collect { |column|
          concat content_tag(:td, elem.attributes[column[:name]])
      }.to_s.html_safe
    end

  }.join().html_safe
 end

 content_tag :table, thead.concat(tbody)

end
5 голосов
/ 05 июля 2011

На самом деле вам не хватает только плюса между тегами контента, вы можете найти похожий вопрос здесь

Rails - вложенный тег контента

Проблема в том, что, возможно, вы получите синтаксическую ошибку из-за того, как вы используете блоки, если вы используете «{}» вместо «do end», вы будете в порядке.

Здесь ( Изменить способ обработки блока ) вы можете найти пример и обходной путь в случае, если вы используете Rails 3, потому что, по-видимому, Rails 3 игнорирует результат оператора collect, когда находится внутри тег содержимого.

1 голос
/ 05 октября 2010

См. Railscast об этом: http://railscasts.com/episodes/208-erb-blocks-in-rails-3 Все это объясняет, как вы управляете своим помощником блока в рельсах 3

0 голосов
/ 24 ноября 2016

Добавление '.join (). Html_safe' в конец каждого раздела сбора.Вот что сработало для меня.

  collection.collect { |elem| 
    concat content_tag(:tr, columns.collect { |column|
      content_tag(:td, elem.attributes[column[:name]])
  })
}.join().html_safe
0 голосов
/ 05 октября 2010

Это отсутствует concat в вашем :tr связанном content_tag.

Обновлении

Что касается побега, возьмитепосмотрите на API документы для content_tag.Вы должны указать, чтобы не избежать этого.Разумеется, в этом случае вы будете нести ответственность за то, что внутри тегов вы хотите экранировать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...