Rails, Как создать таблицу в помощнике с помощью content_tag?
Я определил функцию в помощнике приложения:
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, но они экранированы:/
Ответы
Ответ 1
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
Ответ 2
На самом деле вам не хватает плюс между тегами контента, здесь вы можете найти аналогичный вопрос.
Вложенные в результирующий контент content_tag
Проблема с этим состоит в том, что, возможно, вы получите синтаксическую ошибку из-за того, как вы используете блоки, если вы используете "{}" вместо "do end", вы будете в порядке.
Здесь (Измените способ обработки блока) вы можете найти пример и обходной путь в случае использования Rails 3, потому что очевидно, Rails 3 игнорирует результат команды collect, когда находится внутри тега контента.
Ответ 3
Отсутствует concat
в :tr
<<22 > .
Update
Что касается экранирования, посмотрите api docs для content_tag
. Вам нужно указать, чтобы избежать его. Разумеется, вы несете ответственность за экранирование содержимого внутри тегов, которые вы хотите избежать в этом случае.
Ответ 4
Посмотрите на railscast об этом: http://railscasts.com/episodes/208-erb-blocks-in-rails-3 все объясняет, как вы управляете блочным помощником в рельсах 3
Ответ 5
Добавление '.join(). html_safe' в конец каждого раздела сбора. Это то, что сработало для меня.
collection.collect { |elem|
concat content_tag(:tr, columns.collect { |column|
content_tag(:td, elem.attributes[column[:name]])
})
}.join().html_safe