0

I have been looking at the ruby-docs but have not been able to make sense of them. I have an application that generates a table and stores files in each cell, a user can add another file by clicking on the last box which says "Add file", but I can't figure out how to do this in ruby.

In PHP I would do something like this; if it helps anyone get an idea:

for($i = 0; $i <= $file_array.size; $i++){
  if($i%3=0){
   html .= "</tr><tr>"
  }
  if($i == $array.size){
   //Prevents out of bounds error
   html .= "<td><a href=\"...\">New File Link</a></td>"
  }
 else{
  //We are not out-of-bounds; continue.
  html .= "<td><a href=\"$file_array[$i]\">File Link</a></td>"
 }
}

In ruby I have

 object.files.each_with_index |attachment, i|

but, I don't know if that is what I want to use; I can't figure out how to use it.

Update: I forgot to put table cells in the code.

Travis Pessetto
  • 3,260
  • 4
  • 27
  • 55
  • jtbandes is correct, but here's a good article on the various ways to loop or iterate through a collection in Ruby: http://www.skorks.com/2009/09/a-wealth-of-ruby-loops-and-iterators/ – Jordan Running Aug 16 '11 at 20:14

3 Answers3

3

Ruby's each and each_with_index are kind of like PHP's foreach loop. The variable attachment will be the element of the array:

html = ""
object.files.each_with_index do |attachment, i|
  html << "</tr><tr>" if i % 3 == 0
  html << "<a href=\"#{attachment}\">File Link</a>"
end
html << "<a href=\"...\">New File Link</a>"

And don't forget to sanitize your strings!

Community
  • 1
  • 1
jtbandes
  • 115,675
  • 35
  • 233
  • 266
  • Sorry, I just updated the PHP code a bit, but the problem I had before is the New File link would not go to the newline with the %3. The PHP code forces it to do one more loop to included it but not access the Array. So with this code the new attachment will appear as a 4th column when there is only suppose to be 3. – Travis Pessetto Aug 16 '11 at 20:36
2

You should try to make more use of the functional approaches in ruby and not try to make it the PHP way... Here's an approach I'd have tried:

# make all file links into a new array converted to html code, append
# a "new file" link
files = object.files.map {|link| '<a href="%s">File Link</a>' % link }
files << ('<a href="%s">New File Link</a>' % "...")

# now break this into slices of 3 wrapped with <td>
files = files.each_slice(3).map {|tr| tr.map {|td| "<td>#{td}</td>" }.join }

# now wrap the rows with <tr>
files = files.map {|tr| "<tr>#{tr}</tr>" }.join

This may look complicated but I think it shows the possibilities and power of mapping functions and block parameters, the code is cleaner by using less helper variables, and it is IMHO more readable / understandable. And best of it: It removes the black magic you need to handle the new file link which almost nobody understands when first looking at the for loop.

BTW: I think you are using Rails although your question asked for Ruby in common. I'd recommend to look at the helpers content_tag and link_to which - combined with the map blocks - make your code even more readable and will handle html escaping for you.

hurikhan77
  • 5,881
  • 3
  • 32
  • 47
0
html = ""
object.files.each_slice(3) do |files|
  html << "<tr>"
  files.each do |attachment|
    html << "<a href=\"#{attachment}\">File Link</a>"
  end
  html << "</tr>"
end
html << "<a href=\"...\">New File Link</a>"
fl00r
  • 82,987
  • 33
  • 217
  • 237