2013-07-10 31 views
10

Tôi có một danh sách các giá trị trong cặp url/tiêu đề mà tôi muốn hiển thị. (Cụ thể hơn, mỗi đối tượng có danh sách liên kết riêng của nó, một số có 0, một số có 1, một số có nhiều hơn.) Tôi muốn chúng xuất hiện trong danh sách được phân cách bằng dấu phẩy. Vì vậy, tôi viết điều này trong tập tin .erb tôi:Tôi có thể tạo một mảng liên kết bằng cách sử dụng link_to trong Rails không?

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

Hơi ngạc nhiên của tôi, điều này hiển thị một danh sách bằng dấu phẩy của mã HTML cho các liên kết Tôi muốn tạo ra; nghĩa là, nó đã lấy tất cả các dấu ngoặc nhọn và mã hóa chúng. Chỉ để đảm bảo không có gì vui trong các hàm bậc cao hơn, tôi đã thử một phiên bản cấp bách hơn:

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

với kết quả tương tự. Nhưng tôi không nghĩ tôi đang lạm dụng link_to, bởi vì nếu tôi sửa đổi điều đó thành

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

thì nó thực sự tạo liên kết. Đó là gần như chính xác những gì tôi muốn, ngoại trừ việc có thêm dấu phẩy sau dấu phẩy cuối cùng. Có một số ma thuật đang diễn ra dưới mui xe với link_to mà làm cho nó hành động khác nhau tùy thuộc vào nơi đầu ra của nó là nhóm? Có cách nào để vượt qua ma thuật đó không? Các ngữ nghĩa join sẽ chính xác những gì tôi muốn ở đây, và tôi có thể tìm ra cách cuộn của riêng mình (bằng cách sử dụng each_index, tôi đoán) nhưng nó có vẻ như một giải pháp cực kỳ nặng và không phải Ruby đối với những gì phải là một vấn đề phổ biến.

+1

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

Trả lời

4

Trong khi các đề xuất sử dụng html_safe sẽ nhận được kết quả bạn đang thực hiện, tôi khuyên bạn không nên gắn vòng lặp như vậy trong chế độ xem của bạn. Có một cách hoàn toàn tốt trong đường ray để làm những gì bạn đang tìm kiếm:

Trong tập tin giao diện chính của bạn, nơi bạn đang có của bạn thay đổi vòng lặp nó như thế này:

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

Sau đó tạo một phần links/_link.html.erb

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

Sau đó tạo một phần shared/_comma.html.erb

, 

Điều tuyệt vời về cách tiếp cận này là bạn không phải lo lắng nếu nội dung liên kết của bạn thực sự an toàn và nếu bạn chọn liệt kê hoặc tạo kiểu cho nó theo cách khác thì đơn giản như thay đổi một hoặc cả hai mẫu. Ví dụ: nếu thay vì dấu phẩy, bạn quyết định bạn muốn dọc theo dấu phẩy và sử dụng <br> thay vì , trong mẫu vùng đệm của bạn.

+0

Aha thanks! Tôi đã có một ý tưởng rằng sẽ có một cái gì đó giống như 'html_safe', nhưng * điều này * là những gì tôi đã thực sự tìm kiếm --- Tôi biết có phải là một thành ngữ cho việc này. Lưu ý cho người đọc tương lai của câu hỏi này: Tôi đã buộc phải không có EOL-at-EOF cho tệp chứa phần liên kết để ngăn khoảng trắng giữa liên kết và dấu phẩy, nhưng một khi tôi đã làm nó hoạt động hoàn hảo. – blahedo

+0

Điều này có rất nhiều hướng dẫn. Có vẻ như không phải là thiết kế tốt nhất. –

+0

Vô hướng nói chung là xấu cho khả năng đọc và bảo trì. Có lẽ, nếu bạn giải thích lý do tại sao gắn bó vòng trong xem là xấu, tôi sẽ hiểu lý do của bạn nhiều hơn nữa. –

0

Đường ray sẽ chuyển đổi chuỗi thành html an toàn theo mặc định. Cuộc gọi tham gia của bạn sẽ chuyển các đầu ra liên kết thành một chuỗi, đó là lý do tại sao văn bản này sau đó được thoát. Hãy thử thêm .html_safe sau cuộc gọi tham gia, sẽ cho bạn biết rằng văn bản bạn đang cung cấp là html an toàn và do đó không cần phải thoát. Có thêm về cách làm việc này tại địa chỉ: http://yehudakatz.com/2010/02/01/safebuffers-and-rails-3-0/

+0

Điều này gặp phải vấn đề tương tự như câu trả lời của Jim Lim làm cho mã của bạn gặp rủi ro đối với lỗ hổng dễ bị khai thác. Sử dụng 'safe_join'. –

11

Hãy thử

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

này ra lệnh cho Rails để không thoát khỏi văn bản.

+0

Tôi thích câu trả lời này vì nó làm giảm sự gián đoạn. Indirection nói chung là xấu cho khả năng đọc và bảo trì. –

+4

được _very_ cẩn thận nếu bạn làm điều này. Khi wl.title đến từ một nguồn bên ngoài, đây là một lỗ hổng có thể khai thác được. Sử dụng 'h (wl.title)' hoặc tốt hơn, sử dụng 'safe_join' – levinalex

1

Hãy thử đặt này trong ApplicationHelper bạn

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

Sau đó làm điều này trong mẫu của bạn

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

Bạn có thể sử dụng bất kỳ phân cách bạn thích theo cách này. Bạn cũng không cần phải gọi số html_safe trên toàn bộ. Chỉ có dấu phân cách. Vì vậy, phương pháp này an toàn hơn.

12

Sử dụng safe_join kết hợp với html_safe trên chuỗi phân cách.

Ví dụ:

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

Bạn là vua! – fatfrog

Các vấn đề liên quan