2013-07-10 3 views
10

У меня есть список значений в парах url/title, которые я хотел бы отображать. (Более конкретно, каждый объект имеет свой собственный список ссылок, некоторые с 0, некоторые с 1, некоторые с большим числом.) Я хотел бы, чтобы они отображались в списке, разделенном запятой. Так что я написал это в моем .erb файла:Могу ли я создать массив ссылок, используя link_to в Rails?

<%= links.map{|wl| link_to wl.title, wl.url}.join(', ') %> 

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

<% a = [] %> 
<% links.each do |wl| %> 
    <% a << link_to(wl.title, wl.url) %> 
<% end %> 
<%= a.join(', ') %> 

с, конечно же, один и тот же результат. Но я не думаю, что я злоупотребляя link_to, потому что если я могу изменить, что

<% links.each do |wl| %> 
    <%= link_to(wl.title, wl.url) %>, 
<% end %> 

, то он на самом деле создает ссылки. Это почти именно то, что я хочу, за исключением того, что после последней есть дополнительная запятая. Есть ли какая-то магия под капотом с link_to, что заставляет ее действовать по-разному в зависимости от того, куда идет ее выход? Есть ли способ обойти эту магию? Сеантика join была бы именно такой, какой я хочу здесь, и я могу, очевидно, выяснить, как свернуться с ней (используя, вероятно, каждый_индекс), но это похоже на ужасно тяжелое и нерубивое решение того, что должно быть общей проблемой.

+1

<% = links.map {| з.д. | link_to wl.title, wl.url} .join (',') .html_safe%>? – oldergod

ответ

4

В то время как предложения по использованию html_safe получат результат, на который вы собираетесь пойти, я бы предложил вам не придерживаться таких циклов, как на ваш взгляд. Существует совершенно хороший способ в рельсах, чтобы сделать то, что вы ищете:

В основной файл просмотра, где вы в настоящее время есть ваши изменения контура его к этому:

<%= render partial: 'links/link', collection: links, spacer_template: 'shared/comma' %> 

Затем создать частичную links/_link.html.erb

<%= link_to link.title, link.url %> 

Затем создайте частичный shared/_comma.html.erb

, 

Приятная вещь в этом подходе заключается в том, что вам не нужно беспокоиться, действительно ли ваш контент ссылки безопасен, и если вы решите перечислить или изменить его другим способом, это будет так же просто, как изменить один или оба шаблона. Например, если вместо запятых вы решите, что хотите его вертикально, используйте <br> вместо , в вашем шаблоне spacer.

+0

Aha спасибо! У меня было подозрение, что будет что-то вроде 'html_safe', но * это * то, что я действительно искал --- Я знал, что для этого должна быть идиома. Обратите внимание на будущих читателей этого вопроса: мне пришлось вынудить no-EOL-at-EOF для файла, содержащего частичную ссылку, чтобы предотвратить пробел между ссылкой и запятой, но как только я сделал это, он отлично работал. – blahedo

+0

У этого есть много косвенности. Не похоже на лучший дизайн. –

+0

Направление, как правило, плохое для удобочитаемости и ремонтопригодности. Возможно, если вы объясните, почему склеивание петлей в представлении плохо, я бы больше понял ваши рассуждения. –

0

Rails преобразует строки, чтобы быть html безопасными по умолчанию. Ваш вызов соединения превращает вывод ссылок в строку, поэтому текст исчезает. Попробуйте добавить .html_safe после вызова соединения, который скажет рельсы, что текст, который вы предоставляете, является html безопасным, и поэтому его не нужно экранировать. Там больше о том, как это работает: http://yehudakatz.com/2010/02/01/safebuffers-and-rails-3-0/

+0

Это связано с той же проблемой, что и ответ Джима Лима, подвергает ваш код риску легкой уязвимости. Используйте 'safe_join'. –

11

Попробуйте

<%= links.map{|wl| link_to wl.title, wl.url}.join(', ').html_safe %> 

Это указывает Rails не избежать текста.

+0

Мне нравится этот ответ, потому что он уменьшает косвенность. Направление обычно плохо для удобочитаемости и ремонтопригодности. –

+4

Будьте _very_ осторожны, если вы это сделаете. Когда wl.title поступает из внешнего источника, это уязвимость, которую можно использовать. Используйте 'h (wl.title)' или, лучше, используйте 'safe_join' – levinalex

1

Попробуйте положить это в ApplicationHelper

def sep(separator) 
    ->(a, b){ a << separator.html_safe << b } 
    end 

Затем сделать это в шаблоне

links.map{|wl| link_to wl.title, wl.url}.reduce(&sep(", ")) 

Вы можете использовать любой сепаратор вам нравится этот способ. Вам также не нужно звонить html_safe на все это. Только разделитель. Таким образом, этот метод более безопасен.

12

Используйте safe_join в сочетании с html_safe на разделительной струне.

Пример:

<%= safe_join(links.map { |l| link_to(l.title, l.url) }, ", ".html_safe) %> 
+0

Ты король! – fatfrog

Смежные вопросы