Integrating a Bootstrap image carousel into a static webpage is fairly easy. It's basically copying and pasting from the Bootstrap website, with the developer just needing to add the image links. Even adding the necessary Bootstrap plug-ins to Rails is straightforward. But, what if you want to use the native Rails helper methods, link_to and image_tag? There's a dearth of information about how to keep your Rails app railsy when using this light-weight and flexible Bootstrap component.

We're going to make a full-width image gallery using the Bootstrap modal and carousel plug-ins within a basic Rails app. And use the Rails helper methods to boot. Let's get started.

Basic Rails app

First let's get a basic application going. Run the following commands:

mkdir carouselFolder
cd carouselFolder
rails new galleryApp

After Rails generates the code, get your skeleton app running by starting the server in the same directory as your app.

rails s

You should see the Rails 5.0 Welcome page. Now let's add gem 'bootstrap-sass' to the Gemfile for our Sass powered version of Bootstrap. Also, add the following to your app/assets/stylesheets/application.scss file. Be sure to add the scss extension to the file if it doesn't already exist.

@import "bootstrap-sprockets"
@import "bootstrap"

Now run bundle install from the terminal and restart the rails server.

Be sure to require the Bootstrap js. in your app/assets/javascripts/application.js file. It should look something like this, and this order:

//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require turbolinks
//= require_tree .

Re-boot your rails server.

Now let's generate the page into which we're going to put our image carousel. In your app's directory run the following command:

rails g controller welcome index

We've now generated the controller code for a Welcome page with an index action. Let's now make the Welcome page the root page by changing get 'welcome/index' in your app/config/routes.rb file to this: root 'welcome#index'. Your routes.rb file should look like this:

Rails.application.routes.draw do
  root 'welcome#index'
end

Your opening page will be very uninspiring and look something like this:

<h1>Welcome#index</h1>
Find me in app/views/welcome/index.html.erb

Add basic Bootstrap styling

Now for some basic Bootstrap for our page. Let's add a bootstrap container within the body tag of our app/views/layouts/application.html.erb file.

...
  <body>
    <div class="container-fluid">
      <%= yield %>
    </div>
  </body>
  ...

Now let's start adding a picture gallery to our app/views/welcome/index.rb file. Let make a Bootstrap row with 4 divs for the full-width of the page. The extra column classes will enable our gallery to gracefully collapse on different viewport sizes.

<div class="row">
  <div class="col-md-3 col-sm-3 col-xs-6">
  </div>
  <div class="col-md-3 col-sm-3 col-xs-6">
  </div>
  <div class="col-md-3 col-sm-3 col-xs-6">
  </div>
  <div class="col-md-3 col-sm-3 col-xs-6">
  </div>
</div>

Thumbnail images

Now let's add some images. So our carousel functions somewhat realistically, let's add 4 thumbnail images and 4 full-size images which will be displayed in the carousel to our app/assets/images/ folder. If you don't have images handy you can go to https://placeimg.com/, follow the instructions and download four full-sized images. In Photoshop or another photo editor save thumbnail versions of the same images and place all 8 of them in the app/assets/images/ folder. Now add the path of the thumbnail images to your Rails image_tag methods like so:

<div class="row">
  <div class="col-md-3 col-sm-3 col-xs-6">
    <%= image_tag "placeimg_350_350_nature.jpg", alt: "placeholder image 1",
                  class: "img-responsive" %>
  </div>
  <div class="col-md-3 col-sm-3 col-xs-6">
    <%= image_tag "placeimg_350_350_nature (1).jpg", alt: "placeholder image 2",
                  class: "img-responsive" %>
  </div>
  <div class="col-md-3 col-sm-3 col-xs-6">
    <%= image_tag "placeimg_350_350_nature (2).jpg", alt: "placeholder image 3",
                  class: "img-responsive" %>
  </div>
  <div class="col-md-3 col-sm-3 col-xs-6">
    <%= image_tag "placeimg_350_350_nature (3).jpg", alt: "placeholder image 4",
                  class: "img-responsive" %>
  </div>
</div>

Notice that we've added the Bootstrap img-responsive class and, of course, the alt tag for accessibility. If no alt tag is specified, Rails automatically uses the images' file name when the page's HTML is generated. Your basic Rails page should now be showing 4 thumbnails across the page. Since these images are going to be links that call the Bootstrap Carousel modal, let's enclose the image_tag in a Rails link_to method. We do that by simply enclosing the image_tag within the link_to tag. The arguments for the image_tag method will need to go into parenthesis as we're going to be adding more code to the link_to method later. Each placeholder image div should look like this:

<div class="col-md-3 col-sm-3 col-xs-6">
    <%= link_to image_tag("placeimg_350_350_nature.jpg", alt: "placeholder image 1",
                                          class: "img-responsive")  %>
</div>

Add Bootstrap modal HTML

Now let's place some boilerplate HTML gathered from the Bootstrap website into our page for our modal. This HTML and the built-in Bootstrap javascript will bring up our modals, and within our modal code we'll embed the carousel. Below our image thumbnail image row add the following code:

...

<div class="modal fade" id="myModal">
  <div class="modal-dialog">
      <div class="modal-content">
          <div class="modal-header">
            <div class="pull-left"><h4>Your picture gallery</h4></div>
              <button type="button" class="close" data-dismiss="modal" title="Close">
                <span class="glyphicon glyphicon-remove"></span>
              </button>
          </div>
    <div class="modal-body">

    <!--CAROUSEL CODE WILL GO HERE-->

    </div><!--end modal-body-->
        <div class="modal-footer">
        <div class="pull-left">
        </div>
          <button class="btn-sm close" type="button" data-dismiss="modal">Close</button>
      </div><!--end modal-footer-->
    </div><!--end modal-content-->
  </div><!--end modal-dialoge-->
</div><!--end myModal-->

You can see the nested div classes for the modal, modal-dialog, modal-content, modal-header, modal-body and modal-footer. All of this will be hidden from view until called by clicking a button, or in our case an image.

Add Bootstrap carousel HTML

Now let's start with the enclosing divs for the carousel items. Inside the class="modal-body" div, add the following HTML:

<div id="myGallery" class="carousel slide" data-interval="false">
      <div class="carousel-inner">
      
               <!--Carousel items will go here-->

                </div><!--end carousel-inner-->

    <!--Begin Previous and Next buttons-->
      <a class="left carousel-control" href="#myGallery" role="button" data-slide="prev">
        <span class="glyphicon glyphicon-chevron-left"></span></a> <a class="right carousel-control"
        href="#myGallery" role="button" data-slide="next">
        <span class="glyphicon glyphicon-chevron-right"></span>
      </a>
    </div><!--end carousel-->

So, here's what everything should look like up to this point. It's a good bit of markup, but should be fairly self-evident as to what the HTML is doing.

<div class="modal fade" id="myModal">
  <div class="modal-dialog">
      <div class="modal-content">
          <div class="modal-header">
            <div class="pull-left"><h4>Your picture gallery</h4></div>
              <button type="button" class="close" data-dismiss="modal" title="Close">
                <span class="glyphicon glyphicon-remove"></span>
              </button>
          </div>
    <div class="modal-body">
    <!--CAROUSEL CODE GOES HERE-->
    <div id="myGallery" class="carousel slide" data-interval="false">
      <div class="carousel-inner">

        <!-- Carousel items will go here -->
        
      </div><!--end carousel-inner-->
        <!-- Previous and Next buttons-->
        <a class="left carousel-control" href="#myGallery" role="button" data-slide="prev">
          <span class="glyphicon glyphicon-chevron-left"></span></a> <a class="right carousel-control"
          href="#myGallery" role="button" data-slide="next">
          <span class="glyphicon glyphicon-chevron-right"></span>
        </a>
    </div><!--end myGallery-->

    </div><!--end modal-body-->
        <div class="modal-footer">
        <div class="pull-left">
        </div>
          <button class="btn-sm close" type="button" data-dismiss="modal">Close</button>
      </div><!--end modal-footer-->
    </div><!--end modal-content-->
  </div><!--end modal-dialoge-->
</div><!--end myModal-->

Adding Carousel items

Looking at the Carousel component from the Bootstrap website we see the following code:


<div class="item active">
   <img src="..." alt="First slide">
</div>

Let's now express that using Rails helpers. Instead of using the HTML img tag, let's use the Rails image_tag helper.

<div class="item active">
   <%= image_tag("placeimg_480_640_nature.jpg",
                 alt: "Description of your image",
                 class: "img-responsive") %>
</div>

The active class denotes which image the slideshow will start with. Notice that we've added the HTML alt and class attributes to the options hash after the image_tag source. Let's also add a caption for each image by enclosing a div with the carousel-caption class below our Rails image_tag but within the item class div. Your first Carousel item looks like this:

<div class="item active">
   <%= image_tag("placeimg_480_640_nature.jpg",
                      alt: "Description of your image here",
                      class: "img-responsive") %>
     <div class="carousel-caption">
       <h3>Your caption here</h3>
         <p>Description here</p>
     </div>
</div>

Now repeat the process 3 more times, omitting the active class. Now your code inside the carousel-inner class should look something like this:

...
 <div class="carousel-inner">

    <div class="item active">
      <%= image_tag("placeimg_480_640_nature.jpg",
                    alt: "Image description here",
                    class: "img-responsive") %>
        <div class="carousel-caption">
          <h3>Caption here</h3>
          <p>Caption description here</p>
        </div>
    </div>
    <div class="item">
      <%= image_tag("placeimg_480_640_nature (1).jpg",
                    alt: "Image description here", 
                    class: "img-respponsive") %>
        <div class="carousel-caption">
          <h3>Caption here</h3>
            <p>Caption description here</p>
        </div>
    </div>
    <div class="item">
      <%= image_tag("placeimg_480_640_nature (2).jpg",
                    alt: "Image description here", 
                    class: "img-respponsive") %>
        <div class="carousel-caption">
          <h3>Caption here</h3>
            <p>Caption description here</p>
        </div>
    </div>
    <div class="item">
      <%= image_tag("placeimg_480_640_nature (3).jpg",
                    alt: "Image description here", 
                    class: "img-respponsive") %>
        <div class="carousel-caption">
          <h3>Caption here</h3>
            <p>Caption description here</p>
        </div>
    </div>
...

Adding Bootstrap HTML data attributes

Now all the images are in place and ready to be called by the Carousel modal. However, we need to Railify the a and img tags of the Bootstrap boilerplate for the thumbnail images. First we need to add a data hash to each thumbnail that will toggle the hidden content of the modal without having to write any javascript. The HTML data attrbiutes for a button to activate the modal would look something like this:

<button type="button" data-toggle="modal" data-target="#myModal">Launch modal</button>

But since we're using an image, we'll slightly modify the use. For Rails, this will translate to a data hash, data: { toggle="modal", target="#myModal }, which we'll place directly after the class attribute within the image_tag. The Rails helper will toggle the hidden modal controller element and target the modal with the specified id. Each image_tag should look like this:

<%= link_to image_tag("placeimg_240_320_nature.jpg", alt: "Image description here",
                          class: "img-responsive",
                          data: { toggle: "modal", target: "#myModal" }) %>

Completing the link_to method

Now remember that we've embedded our image_tag within our link_to helper. So the final piece of the puzzle will be to add to our link_to helper the link to the specified element's id for the Carousel, #myGallery, and a data hash that specifies which image to go to on each click. Let's add this code to the end of the link_to method, making sure the code follows the image_tag like so.

<%= link_to image_tag("placeimg_240_320_nature.jpg", alt: "Image description here",
                          class: "img-responsive",
                          data: { toggle: "modal", target: "#myModal" }),
                          "#myGallery", data: { slide_to: "0"} %>

Notice that the final line of the code belongs to the link_to method, while lines two and three belong to the image_tag. Also, upon a close comparison of the code available on the Bootstrap website and the code used here, the Bootstrap HTML data attribute data-slide-to="0" can be expressed within the Rails link helper as a data hash. However, Rails will not accept attributes with a dash, - but will automagically accept underscores. Do this for all of your thumbnails adding a unique ascending value to the slide_to key.

Your finished code

<div class="row">
  <div class="col-md-3 col-sm-3 col-xs-6">
    <%= link_to image_tag("placeimg_240_320_nature.jpg", alt: "Laurie attitude",
                          class: "img-responsive",
                          data: { toggle: "modal", target: "#myModal" }),
                          "#myGallery", data: { slide_to: "0" } %>
  </div>
  <div class="col-md-3 col-sm-3 col-xs-6">
    <%= link_to image_tag("placeimg_240_320_nature-(1).jpg", alt: "placeholder image 2",
                          class: "img-responsive",
                          data: { toggle: "modal", target: "#myModal" }),
                          "#myGallery", data: { slide_to: "1" } %>
  </div>
  <div class="col-md-3 col-sm-3 col-xs-6">
    <%= link_to image_tag("placeimg_240_320_nature-(2).jpg", alt: "placeholder image 3",
                          class: "img-responsive",
                          data: { toggle: "modal", target: "#myModal" }),
                          "#myGallery", data: { slide_to: "2" }  %>
  </div>
  <div class="col-md-3 col-sm-3 col-xs-6">
    <%= link_to image_tag("placeimg_240_320_nature-(3).jpg", alt: "placeholder image 4",
                          class: "img-responsive",
                          data: { toggle: "modal", target: "#myModal"}),
                          "#myGallery", data: { slide_to: "3" }%>
  </div>
</div>

<div class="modal fade" id="myModal">
  <div class="modal-dialog">
      <div class="modal-content">
          <div class="modal-header">
            <div class="pull-left"><h4>Your picture gallery</h4></div>
              <button type="button" class="close" data-dismiss="modal" title="Close">
                <span class="glyphicon glyphicon-remove"></span>
              </button>
          </div>
    <div class="modal-body">
    <!--CAROUSEL CODE GOES HERE-->
    <div id="myGallery" class="carousel slide" data-interval="false">
      <div class="carousel-inner">

        <div class="item active">
          <%= image_tag("placeimg_480_640_nature.jpg",
                        alt: "Image description here",
                        class: "img-responsive") %>
            <div class="carousel-caption">
              <h3>Caption 1 here</h3>
              <p>Caption 1 description here</p>
            </div>
        </div>
        <div class="item">
          <%= image_tag("placeimg_480_640_nature (1).jpg",
                        alt: "Image description here",
                        class: "img-respponsive") %>
            <div class="carousel-caption">
              <h3>Caption 2 here</h3>
                <p>Caption 2 description here</p>
            </div>
        </div>
        <div class="item">
          <%= image_tag("placeimg_480_640_nature (2).jpg",
                        alt: "Image description here",
                        class: "img-respponsive") %>
            <div class="carousel-caption">
              <h3>Caption 3 here</h3>
                <p>Caption 3 description here</p>
            </div>
        </div>
        <div class="item">
          <%= image_tag("placeimg_480_640_nature (3).jpg",
                        alt: "Image description here",
                        class: "img-respponsive") %>
            <div class="carousel-caption">
              <h3>Caption 4 here</h3>
                <p>Caption 4 description here</p>
            </div>
        </div>

      </div><!--end carousel-inner-->
        <!-- Previous and Next buttons-->
        <a class="left carousel-control" href="#myGallery" role="button" data-slide="prev">
          <span class="glyphicon glyphicon-chevron-left"></span></a> <a class="right carousel-control"
          href="#myGallery" role="button" data-slide="next">
          <span class="glyphicon glyphicon-chevron-right"></span>
        </a>
      </div><!-- myGallery-->

    </div><!-- modal-body-->
        <div class="modal-footer">
        <div class="pull-left">
        </div>
          <button class="btn-sm close" type="button" data-dismiss="modal">Close</button>
      </div><!-- modal-footer-->
    </div><!-- modal-content-->
  </div><!-- modal-dialoge-->
</div><!-- myModal-->

Voila! Now you have a working Bootstrap image carousel activated on image clicks using your Rails link_to and image_tag helper methods to generate your the link's and image's HTML. By simply copying and pasting this code and adding your own images and image paths you can adapt this to your own app's requirements and styling.