Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Ruby

Skip the first image in an .each do statement

I'm using bootstrap's carousel, but one of the div classes inside has to be set active for it to work. And if I set it to active inside the do statement it applies to all of them, I need to be able to get the first image, set it as active, then start a do statement with an offset of 1, so it skips the first image that I will already have displayed, and get the rest of the images.

<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">

          <!-- Wrapper for slides -->

          <div class="carousel-inner">

            <%@item.images.each do |image| %>

                <div class="item">

                  <div class="text-center"><%=link_to image_tag( image.image.to_s, size: "150x150" ), image.image.to_s,:target => '_blank' %></div>

                </div>

            <%end%>

          </div>

          <!-- Controls -->

          <a class="left carousel-control" href="#carousel-example-generic" data-slide="prev">

            <span class="glyphicon glyphicon-chevron-left"></span>

          </a>

          <a class="right carousel-control" href="#carousel-example-generic" data-slide="next">

            <span class="glyphicon glyphicon-chevron-right"></span>

          </a>

        </div>

Hi John,

Could you post the relevant code you're using to make it easier for someone to help you?

4 Answers

I don't have any ruby experience but I can try to help you from a general programming standpoint.

This might not be an efficient solution but you could set a boolean variable to true before the loop which could indicate whether you are going through the loop for the first time. Then inside your loop check if that boolean is true, and if it is, you could then output the active class in your div.item and also set the boolean to false so that the active class is never output again.

I would so something like this (i have no idea the class names or the layout, I made a guess):

<div class="wrapper">
   <div class="carousel active">
      This is the first one, it's already marked as active
   </div>
    <% @items.each do |item| %>
        <div class="carousel">
           <%= item %>
        </div>
    <% end %>
</div>

Alternatively, if you do it using unordered lists "[ul]" and "[li]" its the same thing:

<div class="wrapper">
   <ul class="carousel 
     <li class="active">
      This is the first one, it's already marked as active
      </li>
    <% @items.each do |item| %>
        <li class="not-active">
           <%= item %>
        </li>
    <% end %>
   </ul>
</div>

If you prefer to do it as Brandon Barrette has suggested where you set up your active div before the loop then this stackoverflow answer is along the lines of what you want. http://stackoverflow.com/a/11851421

That requires a certain setup though that probably doesn't match your image setup.

To make it work for the general case maybe you could shift() the first image off your array and use that to set up your first active div. Then the loop would simply operate on the remaining images in the array, with the first one having already been removed.

<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">

          <!-- Wrapper for slides -->

          <div class="carousel-inner">

            <!-- I would need the code to grab the first image togo here so I could manually set it active -->

            <%@item.images.each do |image| %> <!-- and then here I would need the code to skip the first image since it is already accounted for above -->

                <div class="item">

                  <div class="text-center"><%=link_to image_tag( image.image.to_s, size: "150x150" ), image.image.to_s,:target => '_blank' %></div>

                </div>

            <%end%>

          </div>

          <!-- Controls -->

          <a class="left carousel-control" href="#carousel-example-generic" data-slide="prev">

            <span class="glyphicon glyphicon-chevron-left"></span>

          </a>

          <a class="right carousel-control" href="#carousel-example-generic" data-slide="next">

            <span class="glyphicon glyphicon-chevron-right"></span>

          </a>

        </div>

is the code I have.

For anyone that comes across this, the best way is to use a counter

<div class="col-md-4">

        <div id="carousel-example-generic" class="carousel slide" data-ride="carousel">

          <!-- Wrapper for slides -->

          <div class="carousel-inner">

            <% i = 0 %>

            <%@item.images.each do |image| %>

                <% if i == 0 %>

                    <div class="item active">

                    <% i = i+1 %>

                <%else %>

                    <div class="item">

                <%end%>

                  <div class="text-center"><%=link_to image_tag( image.image.to_s, size: "150x150" ), image.image.to_s,:target => '_blank' %></div>

                </div>

            <%end%>

          </div>

          <!-- Controls -->

          <a class="left carousel-control" href="#carousel-example-generic" data-slide="prev">

            <span class="glyphicon glyphicon-chevron-left"></span>

          </a>

          <a class="right carousel-control" href="#carousel-example-generic" data-slide="next">

            <span class="glyphicon glyphicon-chevron-right"></span>

          </a>

        </div>

    </div>

John Shofstall I may not have been very clear in my answer using boolean variables but it's the same thing as what you've done here. You would set a boolean variable to true before the loop and then set that boolean variable to false inside the if block so that the if block never gets executed again.

Out of curiosity, did the other solution of shifting the first image off the array not work out? Or was that a less desirable solution because of the markup duplication before and inside the loop when all that is really different is the "active" class?

Jason, I didn't try the shift method. At my work I'm the UI/UX developer and my colleague that knows rails said the counter would be easier. And you are correct about the duplicate code part. I used these forums because I've had good results here and wanted to get the changes made before he got back the next work day.

Thanks for the response back.

I had wondered if ruby had the equivalent of a for loop because then you would have a counter built in. It seems to not have the traditional for loop but there is .each_with_index I think this could save you a few lines of code if you need to do something like this again in the future. You wouldn't need to set i = 0 or i = i + 1

Something like this if I understand it right:

<div class="carousel-inner">

            <%@item.images.each_with_index do |image, index| %>

                <% if index == 0 %>

                    <div class="item active">

                <%else %>

                    <div class="item">

                <%end%>