<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>ASCIIcasts - Full Episode Feed</title>
    <description>The latest episodes from ASCIIcasts</description>
    <link>http://asciicasts.com/</link>
    <pubDate>Sun, 11 Mar 2012 21:57:41 +0000</pubDate>
    <ttl>1440</ttl>
    <item>
      <title>Better SASS With Bourbon</title>
      <description>&lt;p&gt;If you&amp;rsquo;re tired of typing vendor-specific prefixes for CSS properties you should take a look at the &lt;a href="http://thoughtbot.com/bourbon/"&gt;Bourbon library&lt;/a&gt; which includes several SASS mixins and functions to make working with CSS more convenient. In this episode we&amp;rsquo;ll show you how to use it in a Rails application.&lt;/p&gt;

&lt;h3&gt;Adding Bourbon to a Rails Application&lt;/h3&gt;

&lt;p&gt;The application we&amp;rsquo;ll be working with is shown below. Its design needs some work so we&amp;rsquo;ll add Bourbon to the app and use some of its features to improve the way the page looks.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/1045/original/E330I01.png" width="800" height="420" alt="Our projects page."/&gt;
&lt;/div&gt;

&lt;p&gt;Installing Bourbon is easy. All we need to do is add it to the gemfile and run &lt;code&gt;bundle&lt;/code&gt;.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/Gemfile&lt;/p&gt;
&lt;pre class="ruby"&gt;source &amp;#x27;https://rubygems.org&amp;#x27;

gem &amp;#x27;rails&amp;#x27;, &amp;#x27;3.2.2&amp;#x27;

# Bundle edge Rails instead:
# gem &amp;#x27;rails&amp;#x27;, :git =&amp;gt; &amp;#x27;git://github.com/rails/rails.git&amp;#x27;

gem &amp;#x27;sqlite3&amp;#x27;


# Gems used only for assets and not required
# in production environments by default.
group :assets do
  gem &amp;#x27;sass-rails&amp;#x27;,   &amp;#x27;~&amp;gt; 3.2.3&amp;#x27;
  gem &amp;#x27;coffee-rails&amp;#x27;, &amp;#x27;~&amp;gt; 3.2.1&amp;#x27;

  # See https://github.com/sstephenson/execjs#readme for more supported runtimes
  # gem &amp;#x27;therubyracer&amp;#x27;

  gem &amp;#x27;uglifier&amp;#x27;, &amp;#x27;&amp;gt;= 1.0.3&amp;#x27;
end

gem &amp;#x27;jquery-rails&amp;#x27;
gem &amp;#x27;bourbon&amp;#x27;&lt;/pre&gt;

&lt;p&gt;To use Bourbon with Rails&amp;rsquo; asset pipeline we&amp;rsquo;ll need to change the way that the default &lt;code&gt;application.css&lt;/code&gt; file works. By default this file will use a Sprockets manifest to load each of the other stylesheet assets. The problem with this is that Sprockets compiles each SASS file into CSS individually which makes it difficult to share the Bourbon mixins across the SASS files. To fix this we can use SASS to load all the &lt;code&gt;scss&lt;/code&gt; files instead of Sprockets.&lt;/p&gt;

&lt;p&gt;We&amp;rsquo;ll need to rename our the &lt;code&gt;application.css&lt;/code&gt; file to &lt;code&gt;application.css.scss&lt;/code&gt;, then we can then remove the Sprockets manifest and use SASS&amp;rsquo;s &lt;code&gt;@import&lt;/code&gt; command to pull in the files that we want to include. For now we&amp;rsquo;ll just include the &lt;code&gt;bourbon&lt;/code&gt; file provided by the gem.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/stylesheets/application.css.scss&lt;/p&gt;
&lt;pre class="css"&gt;@import &amp;quot;bourbon&amp;quot;;&lt;/pre&gt;

&lt;p&gt;We&amp;rsquo;ll need to restart the Rails server for these changes to be picked up. After we&amp;rsquo;ve done that when we reload the page all the styling has gone.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/1046/original/E330I02.png" width="800" height="420" alt="The page now has no styling at all."/&gt;
&lt;/div&gt;

&lt;p&gt;If we look at the &lt;code&gt;/assets/application.css&lt;/code&gt; file in the browser we&amp;rsquo;ll see that it&amp;rsquo;s blank. Bourbon doesn&amp;rsquo;t add any CSS to our application directly, it just makes it more convenient for us to add our own CSS through SASS. It&amp;rsquo;s still up to us to write all the CSS we need for our application so we&amp;rsquo;ll put the &lt;code&gt;layout&lt;/code&gt; and &lt;code&gt;project&lt;/code&gt; files back in &lt;code&gt;application.css.scss&lt;/code&gt;. We set up these CSS files earlier but now we&amp;rsquo;ll be able to use Bourbon in them.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/stylesheets/application.css.scss&lt;/p&gt;
&lt;pre class="css"&gt;@import &amp;quot;bourbon&amp;quot;;
@import &amp;quot;layout&amp;quot;;
@import &amp;quot;projects&amp;quot;;&lt;/pre&gt;

&lt;p&gt;When we reload the page now it will bring us back to the design we had earlier.&lt;/p&gt;

&lt;h3&gt;Modifying The Header&lt;/h3&gt;

&lt;p&gt;The first improvement we&amp;rsquo;ll make to our design is to change the font. The page currently uses the browser&amp;rsquo;s default font, which is usually Times New Roman. Bourbon includes a &lt;a href="http://thoughtbot.com/bourbon/#font-family"&gt;&lt;code&gt;font-family&lt;/code&gt; add-on&lt;/a&gt; which provides aeveral variables for setting the type of font. These include fallback fonts for when the first font required isn&amp;rsquo;t available. We&amp;rsquo;ll use one of these to set the body&amp;rsquo;s font.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/stylesheets/layout.css.scss&lt;/p&gt;
&lt;pre class="css"&gt;body {
  margin: 0;
  padding: 0;
  background-color: #FFF;
  font-size: 14px;
  font-family: $verdana;
}&lt;/pre&gt;

&lt;p&gt;Next we&amp;rsquo;ll add a gradient to the header. Bourbon provides a &lt;a href="http://thoughtbot.com/bourbon/#linear-gradient"&gt;&lt;code&gt;linear-gradient&lt;/code&gt; module&lt;/a&gt; and we can use this to add a gradient and set its colours. We&amp;rsquo;ll add a gradient that fades from light grey to a darker grey. Note that we haven&amp;rsquo;t set a direction for the gradient; this means that the default value of top will be used.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/stylesheets/layout.css.scss&lt;/p&gt;
&lt;pre class="css"&gt;#header {
  color: #FFF;
  padding: 15px 100px;
  font-size: 30px;
  font-weight: bold;
  @include linear-gradient(#777, #444);
}&lt;/pre&gt;

&lt;p&gt;A default background colour is included in &lt;code&gt;linear-gradient&lt;/code&gt; so we&amp;rsquo;ve removed the &lt;code&gt;background-color&lt;/code&gt; property from the header. We also want a drop shadow under the header and Bourbon provides a &lt;a href="http://thoughtbot.com/bourbon/#box-shadow"&gt;mixin&lt;/a&gt; for adding these. We can use this in a similar way to the &lt;code&gt;box-shadow&lt;/code&gt; CSS3 property but the mixin will generate all the vendor-specific prefixes for us. We&amp;rsquo;ll add a black shadow with no offset and with a six pixel shadow with a three pixel spread.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/stylesheets/layout.css.scss&lt;/p&gt;
&lt;pre class="css"&gt;#header {
  background-color: #555;
  color: #FFF;
  padding: 15px 100px;
  font-size: 30px;
  font-weight: bold;
  @include linear-gradient(#777, #444);
  @include box-shadow(0 0 6px 3px #000);
}&lt;/pre&gt;

&lt;p&gt;When we reload the page now these changes can be seen.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/1047/original/E330I03.png" width="800" height="420" alt="The header now has a gradient and drop shadow."/&gt;
&lt;/div&gt;

&lt;h3&gt;Modifying The Items&lt;/h3&gt;

&lt;p&gt;Next we&amp;rsquo;ll make some changes to the list of items. First we&amp;rsquo;ll add rounded corners to the box that surrounds each project. Needless to say Bourbon has a &lt;a href="http://thoughtbot.com/bourbon/#border-radius"&gt;&lt;code&gt;border-radius&lt;/code&gt; module&lt;/a&gt; to do just this. The project-specific styling is in a &lt;code&gt;projects.css.scss&lt;/code&gt; file so we&amp;rsquo;ll make this change there and add a six pixel radius.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/stylesheets/projects.css.scss&lt;/p&gt;
&lt;pre class="css"&gt;.project {
  border: solid 1px #AAA;
  margin: 20px 0;
  padding: 7px 12px;
  @include border-radius(6px);
  
  &amp;amp;:hover { background-color: #F8FCCF; }
  
  h2 {
    margin: 0;
    a { text-decoration: none; }
  }
}&lt;/pre&gt;

&lt;p&gt;Next we&amp;rsquo;ll change the way that the background colour of each item changes when we hover over it. Instead of it changing immediately we&amp;rsquo;d like it to fade in to that colour. We can use &lt;a href="http://thoughtbot.com/bourbon/#transitions"&gt;transitions&lt;/a&gt; to do this, passing in the attribute we want to change, the time it should take to do the change and the easing effect.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/stylesheets/projects.css.scss&lt;/p&gt;
&lt;pre class="css"&gt;.project {
  border: solid 1px #AAA;
  margin: 20px 0;
  padding: 7px 12px;
  @include border-radius(6px);
  @include transition(all, 500ms, ease-in-out);
  
  &amp;amp;:hover { background-color: #F8FCCF; }
  
  h2 {
    margin: 0;
    a { text-decoration: none; }
  }
}&lt;/pre&gt;

&lt;p&gt;Now the background colour will fade in over half a second when we hover over a project and fade out over the same time when the cursor moves out.&lt;/p&gt;

&lt;p&gt;The last change we&amp;rsquo;ll make to this page is to improve the &amp;ldquo;New Project&amp;rdquo; link. We&amp;rsquo;d like it to look more like a button instead and Bourbon includes a &lt;a href="http://thoughtbot.com/bourbon/#buttons"&gt;buttons add-on&lt;/a&gt; that we can use to make different styles of button. Our link has a &lt;code&gt;new_project&lt;/code&gt; class so we&amp;rsquo;ll use that to style it and turn the link into a simple green button.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/stylesheets/projects.css.scss&lt;/p&gt;
&lt;pre class="css"&gt;.new_project {
  @include button(simple, #3FB344); 
}&lt;/pre&gt;

&lt;p&gt;When we reload the page now we&amp;rsquo;ll see the rounded corners and the styled link. (You&amp;rsquo;ll have to take the background colour fade on trust.)&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/1048/original/E330I04.png" width="800" height="420" alt="The rest of the page is now styled the way we want it."/&gt;
&lt;/div&gt;

&lt;p&gt;The button has inherited some attributes from the anchor tag such as the underlined text and we want it to be a little larger. We&amp;rsquo;ll add some more CSS to do this.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/stylesheets/projects.css.scss&lt;/p&gt;
&lt;pre class="css"&gt;.new_project {
  @include button(simple, #3FB344); 
  text-decoration: none;
  font-size: 16px;
}&lt;/pre&gt;

&lt;p&gt;We now have a nice button for adding a new project.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/1049/original/E330I05.png" width="800" height="420" alt="The button is now styled too."/&gt;
&lt;/div&gt;

&lt;h3&gt;An Example Of The CSS That Bourbon Generates&lt;/h3&gt;

&lt;p&gt;Now that the page is looking better let&amp;rsquo;s look at the CSS that Bourbon has generated. We can&amp;rsquo;t show it all here as there&amp;rsquo;s a lot of it but as an example here&amp;rsquo;s the generated CSS for the header and we can see the code for the gradient that we added.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;css&lt;/p&gt;
&lt;pre class="css"&gt;#header {
  background-color: #555;
  color: #FFF;
  padding: 15px 100px;
  font-size: 30px;
  font-weight: bold;
  background-color: #777777;
  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #777777), color-stop(100%, #444444));
  background-image: -webkit-linear-gradient(top, #777777, #444444);
  background-image: -moz-linear-gradient(top, #777777, #444444);
  background-image: -ms-linear-gradient(top, #777777, #444444);
  background-image: -o-linear-gradient(top, #777777, #444444);
  background-image: linear-gradient(top, #777777, #444444);
  -webkit-box-shadow: 0 0 6px 3px black;
  -moz-box-shadow: 0 0 6px 3px black;
  box-shadow: 0 0 6px 3px black;
}&lt;/pre&gt;

&lt;p&gt;There&amp;rsquo;s a lot of code here that we&amp;rsquo;ve not had to write manually thanks to Bourbon.&lt;/p&gt;

&lt;p&gt;SASS also includes several functions that can help out with generating CSS when dealing with colour changes, variations and adjustments. There&amp;rsquo;s more information in &lt;a href="http://railscasts.com/episodes/268-sass-basics"&gt;episode 268&lt;/a&gt; on what can be done with SASS alone.&lt;/p&gt;
</description>
      <pubDate>Sun, 11 Mar 2012 21:57:22 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/330-better-sass-with-bourbon</guid>
      <link>http://asciicasts.com/episodes/330-better-sass-with-bourbon</link>
    </item>
    <item>
      <title>Twitter Bootstrap Basics</title>
      <description>&lt;p&gt;&lt;a href="http://twitter.github.com/bootstrap/"&gt;Twitter&amp;rsquo;s Bootstrap&lt;/a&gt; helps you build beautiful web apps quickly. It provides a variety of CSS and JavaScript for making layouts, navigation, forms and a lot more and it even includes support for responsive web design. As an example, if you visit its homepage and alter the width of the browser window the page layout will change to best fit that width. This can really improve the experience of using web applications on mobile devices.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/1023/original/E328I01.png" width="801" height="545" alt="Twitter Bootstrap&amp;rsquo;s homepage."/&gt;
&lt;/div&gt;

&lt;p&gt;It&amp;rsquo;s well worth taking some time to explore the Twitter Bootstrap website to see everything that it provides but in this episode we&amp;rsquo;re going to show you how you can use it with a Rails application. One option is to download the static CSS and JavaScript by clicking on the &amp;ldquo;Download Bootstrap&amp;rdquo; button and then move the appropriate files into &lt;code&gt;/app/assets&lt;/code&gt; directory. This isn&amp;rsquo;t the best approach if you&amp;rsquo;re using Rails, however. Twitter Bootstrap is written using LESS, which is a CSS preprocessor and which is very similar to the SASS used by Rails.&lt;/p&gt;

&lt;p&gt;To get the most flexibility from Twitter Bootstrap it&amp;rsquo;s best to use it with a dynamic language, such as LESS, instead of using the static compiled files which it outputs. To get LESS working with Rails we&amp;rsquo;ll need the help of some Ruby gems. There are several gems available for integrating Bootstrap with Rails. In this episode we&amp;rsquo;ll be using the &lt;a href="https://github.com/seyhunak/twitter-bootstrap-rails"&gt;twitter-bootstrap-rails gem&lt;/a&gt; but we&amp;rsquo;ll mention some of the alternatives later. We&amp;rsquo;ve chosen this gem as it works directly with LESS and offers some nice generators to help us get started. We&amp;rsquo;re getting a little ahead of ourselves here, though as we don&amp;rsquo;t even have a Rails application to work with yet.&lt;/p&gt;

&lt;h3&gt;Adding Bootstrap to a New Rails Application.&lt;/h3&gt;

&lt;p&gt;We&amp;rsquo;ll start with a new app that we&amp;rsquo;ll call &lt;code&gt;store&lt;/code&gt; and we&amp;rsquo;ll generate a scaffold for a &lt;code&gt;Product&lt;/code&gt; model so that we have something to work with.&lt;/p&gt;


&lt;p class="codeFilePath"&gt;terminal&lt;/p&gt;
&lt;pre class="terminal"&gt;
$ rails new store
$ cd store
$ rails g scaffold product name price:decimal --skip-stylesheets
$ rake db:migrate
&lt;/pre&gt;

&lt;p&gt;Note that we&amp;rsquo;ve used the &lt;code&gt;--skip-stylesheets&lt;/code&gt; option in the scaffold as we want to use Bootstrap&amp;rsquo;s CSS instead of the scaffolding&amp;rsquo;s. We&amp;rsquo;ve also migrated the database so that the products table is created. Here&amp;rsquo;s what the generated scaffold page looks like. It isn&amp;rsquo;t very pretty as we don&amp;rsquo;t have any styling applied. It&amp;rsquo;s time to add Twitter Bootstrap.&lt;/p&gt;


&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/1024/original/E328I02.png" width="801" height="280" alt="The products page without any styling."/&gt;
&lt;/div&gt;

&lt;p&gt;The first step is to add the &lt;code&gt;twitter-bootstrap-rails&lt;/code&gt; gem to the &lt;code&gt;assets&lt;/code&gt; group in the gemfile. This gem is only needed in this group as it&amp;rsquo;s only used by the assets pipeline. If we&amp;rsquo;re using static assets in production then it won&amp;rsquo;t be needed.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/Gemfile&lt;/p&gt;
&lt;pre class="ruby"&gt;
# Gems used only for assets and not required
# in production environments by default.
group :assets do
  gem 'sass-rails',   '~&gt; 3.2.3'
  gem 'coffee-rails', '~&gt; 3.2.1'

  # See https://github.com/sstephenson/execjs#readme for more supported runtimes
  # gem 'therubyracer'

  gem 'uglifier', '&gt;= 1.0.3'
  gem 'twitter-bootstrap-rails'
end
&lt;/pre&gt;

&lt;p&gt;We&amp;rsquo;ll need to run &lt;code&gt;bundle&lt;/code&gt; next to install &lt;code&gt;twitter-bootstrap-rails&lt;/code&gt; along with its dependencies. This gem has a number of dependencies including &lt;code&gt;libv8&lt;/code&gt; and &lt;code&gt;less-rails&lt;/code&gt; and these enable our app to interpret the LESS syntax.  Now that we have Bootstrap installed we can run its generator to install it.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;terminal&lt;/p&gt;
&lt;pre class="terminal"&gt;
$ rails g bootstrap:install
      insert  app/assets/javascripts/application.js
      create  app/assets/javascripts/bootstrap.js.coffee
      create  app/assets/stylesheets/bootstrap_and_overrides.css.less
        gsub  app/assets/stylesheets/application.css
        gsub  app/assets/stylesheets/application.css
&lt;/pre&gt;

&lt;p&gt;This sets up Bootstrap under the &lt;code&gt;/app/assets&lt;/code&gt; directory. One key file that was generated is &lt;code&gt;bootstrap_and_overrides.css.less&lt;/code&gt;. This file loads up Bootstrap and it&amp;rsquo;s a good place to customize the styling to suit your application. After we restart the server and reload the page we can see that the styling is already starting to look better, but there&amp;rsquo;s still a lot to do.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/1025/original/E328I03.png" width="801" height="280" alt="Adding Twitter bootstrap to the app gives the home page some styling."/&gt;
&lt;/div&gt;

&lt;h3&gt;Improving The Layout&lt;/h3&gt;

&lt;p&gt;We&amp;rsquo;ll focus first on the application&amp;rsquo;s layout. The &lt;code&gt;twitter-bootstrap-rails&lt;/code&gt; gem provides a &lt;code&gt;bootstrap:layout&lt;/code&gt; generator for generating a layout file, but we won&amp;rsquo;t use that here. Instead we&amp;rsquo;ll walk through the steps required to change the layout to give you a better idea as to how Twitter Bootstrap works.&lt;/p&gt;

&lt;p&gt;There are two kinds of layouts, fixed and fluid. A fixed layout is a specific pixel width, while a fluid layout will expand to the full width of the browser. Specifying either &lt;code&gt;container&lt;/code&gt; or &lt;code&gt;container-fluid&lt;/code&gt; as the class of the wrapper &lt;code&gt;div&lt;/code&gt; will determine which layout is used. We&amp;rsquo;re going to use a fixed-width layout here so we&amp;rsquo;ll add a &lt;code&gt;div&lt;/code&gt; with a &lt;code&gt;container&lt;/code&gt; class to the &lt;code&gt;body&lt;/code&gt; of the layout file.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/layouts/application.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;Store&lt;/title&gt;
  &lt;%= stylesheet_link_tag    "application", :media =&gt; "all" %&gt;
  &lt;%= javascript_include_tag "application" %&gt;
  &lt;%= csrf_meta_tags %&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class="container"&gt;
  &lt;%= yield %&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;/pre&gt;

&lt;p&gt;Twitter Bootstrap uses a 12-column grid system. This makes it easy to implement column-based layout designs by specifying the width of each column. This layout is responsive so if we reduce the width of the browser the layout will change accordingly. Let&amp;rsquo;s say that we want a sidebar in our design and that we want this to take up 25% of the width of the page. We can do that by modifying the layout file like this. We&amp;rsquo;ll just add some static text to the sidebar for now.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/layouts/application.html.erb&lt;/p&gt;
&lt;pre class="html"&gt;
&amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;
  &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;span9&amp;quot;&amp;gt;&amp;lt;%= yield %&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;div class=&amp;quot;span3&amp;quot;&amp;gt;
      &amp;lt;h2&amp;gt;About Us&amp;lt;/h2&amp;gt;
      &amp;lt;p&amp;gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.&amp;lt;/p&amp;gt;	
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;When we reload the page now we&amp;rsquo;ll see our new two-column layout.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/1026/original/E328I04.png" width="801" height="426" alt="Our two column layout has a sidebar on the right talking up around 25% of the width of the window."/&gt;
&lt;/div&gt;

&lt;h3&gt;Adding a Navigation Bar&lt;/h3&gt;

&lt;p&gt;Next we&amp;rsquo;ll add a navigation bar to the top of the page with some links for navigating the site. The components section of the &lt;a href="http://twitter.github.com/bootstrap/components.html"&gt;documentation&lt;/a&gt; describes the various navigation options that Twitter Bootstrap provides, including a &lt;a href="http://twitter.github.com/bootstrap/components.html#navbar"&gt;navbar&lt;/a&gt;. This navbar can be customized to suit our needs and we can add links, dropdown sections, search fields and so on. The documentation has good examples of how we can add each type of item. We&amp;rsquo;ll add our navbar at the top of the layout page&amp;rsquo;s body.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/layouts/application.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;div class=&amp;quot;navbar navbar-fixed-top&amp;quot;&amp;gt;
  &amp;lt;div class=&amp;quot;navbar-inner&amp;quot;&amp;gt;
    &amp;lt;div class=&amp;quot;container&amp;quot;&amp;gt;
      &amp;lt;a class=&amp;quot;btn btn-navbar&amp;quot; data-toggle=&amp;quot;collapse&amp;quot; data-target=&amp;quot;.collapse&amp;quot;&amp;gt;
        &amp;lt;span class=&amp;quot;icon-bar&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;icon-bar&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span class=&amp;quot;icon-bar&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;
      &amp;lt;/a&amp;gt;
      &amp;lt;a class=&amp;quot;brand&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Some Store&amp;lt;/a&amp;gt;
      &amp;lt;div class=&amp;quot;nav-collapse&amp;quot;&amp;gt;
        &amp;lt;ul class=&amp;quot;nav&amp;quot;&amp;gt;
          &amp;lt;li&amp;gt;&amp;lt;%= link_to &amp;quot;Browse Products&amp;quot;, products_path %&amp;gt;&amp;lt;/li&amp;gt;
          &amp;lt;li&amp;gt;&amp;lt;%= link_to &amp;quot;Price List&amp;quot; %&amp;gt;&amp;lt;/li&amp;gt;
          &amp;lt;li&amp;gt;&amp;lt;%= link_to &amp;quot;Contact Us&amp;quot; %&amp;gt;&amp;lt;/li&amp;gt;
          &amp;lt;li&amp;gt;&amp;lt;%= link_to &amp;quot;Cart&amp;quot; %&amp;gt;&amp;lt;/li&amp;gt;
        &amp;lt;/ul&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Our navigation has a brand name section and some placeholder links. The section at the top is interesting. It handles the collapsing behaviour when the browser resizes for the navigation. Reloading the page now will show our new navbar.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/1027/original/E328I05.png" width="801" height="426" alt="Our site now has a navigation bar at the top, though it&amp;rsquo;s hidden as our browser window isn't wide enough."/&gt;
&lt;/div&gt;

&lt;p&gt;Note that we see the collapsed version of the navigation. This is because the browser window&amp;rsquo;s width is set to around 800px which means that it isn&amp;rsquo;t wide enough to show the full version. If we widen the window the navigation will appear.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/1028/original/E328I06.png" width="801" height="426" alt="Widening the browser window shows the navbar, but the top part of the main page is now hidden."/&gt;
&lt;/div&gt;

&lt;p&gt;There&amp;rsquo;s a problem when we do this, however. The top part of the page is covered by the navbar. This is a side effect of using a fixed navbar and the documentation tells us that to avoid this unwanted effect we should add at least 40 pixels of padding to the top of the &lt;code&gt;body&lt;/code&gt; element between the Bootstrap CSS and the responsive CSS. We do this inside the &lt;code&gt;bootstrap_and_overrides&lt;/code&gt; CSS file. This file includes the &lt;code&gt;bootstrap&lt;/code&gt; and &lt;code&gt;responsive&lt;/code&gt; files and the documentation says that padding needs to be added between these.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/stylesheets/bootstrap_and_overrides.css&lt;/p&gt;
&lt;pre class="css"&gt;
@import "twitter/bootstrap/bootstrap";

body { padding-top: 60px; } 

@import "twitter/bootstrap/responsive";

// Set the correct sprite paths
@iconSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings.png');
@iconWhiteSpritePath: asset-path('twitter/bootstrap/glyphicons-halflings-white.png');

// Your custom LESS stylesheets goes here
//
// Since bootstrap was imported above you have access to its mixins which
// you may use and inherit here
//
// If you'd like to override bootstrap's own variables, you can do so here as well
// See http://twitter.github.com/bootstrap/less.html for their names and documentation
//
// Example:
// @linkColor: #ff0000;
&lt;/pre&gt;

&lt;p&gt;When we reload the page now the top of it is no longer hidden behind the navbar.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/1029/original/E328I07.png" width="801" height="420" alt="With padding added to the body the top part of the page is now visible again."/&gt;
&lt;/div&gt;

&lt;h3&gt;Final Tweaks to The Header&lt;/h3&gt;

&lt;p&gt;Our application&amp;rsquo;s layout file is pretty much complete now but there are a couple of thing we need to add in the head section to ensure that it works everywhere.&lt;/p&gt; 

&lt;p class="codeFilePath"&gt;/app/views/layouts/application.html.erb&lt;/p&gt;
&lt;pre class="html"&gt;
&amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;Store&amp;lt;/title&amp;gt;
  &amp;lt;!--[if lt IE 9]&amp;gt;
    &amp;lt;script src=&amp;quot;http://html5shim.googlecode/svn/trunk/html5.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;![endif]--&amp;gt;
  &amp;lt;%= stylesheet_link_tag    &amp;quot;application&amp;quot;, :media =&amp;gt; &amp;quot;all&amp;quot; %&amp;gt;
  &amp;lt;%= javascript_include_tag &amp;quot;application&amp;quot; %&amp;gt;
  &amp;lt;%= csrf_meta_tags %&amp;gt;
  &amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width, initial-scale=1.0&amp;quot;&amp;gt;
&amp;lt;/head&amp;gt;
&lt;/pre&gt;

&lt;p&gt;The first piece of code we&amp;rsquo;ve added here improves the HTML 5 support in older versions of Internet Explorer. The second is a viewport &lt;code&gt;meta&lt;/code&gt; tag and this fixes the responsive design behaviour on mobile devices.&lt;/p&gt; 

&lt;h3&gt;Improving The Views&lt;/h3&gt;

&lt;p&gt;What about the other views in this application? There&amp;rsquo;s a lot that Twitter Bootstrap provides that can improve the look of the scaffold-generated code we have. First we&amp;rsquo;ll add a few product records so that we have some more content to work with.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/1030/original/E328I08.png" width="800" height="420" alt="The products index page now shows a list of six products."/&gt;
&lt;/div&gt;


&lt;p&gt;Next we&amp;rsquo;ll use Twitter Bootstrap to improve the look of this page. Instead of walking through each change manually we&amp;rsquo;ll use one of the generators provided by the gem.  This generator is called &lt;code&gt;themed&lt;/code&gt; and is designed to work on top of scaffolding so we need to pass it the name of a scaffold. We also pass in the &lt;code&gt;-f&lt;/code&gt; option to force it to overwrite the generated view files.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;terminal&lt;/p&gt;
&lt;pre class="terminal"&gt;
$ rails g bootstrap:themed products -f
&lt;/pre&gt;

&lt;p&gt;When we reload the products page now it looks much better. The table is a lot cleaner and the &amp;ldquo;edit&amp;rdquo; and &amp;ldquo;destroy&amp;rdquo; links now look like buttons instead of like plain text links.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/1031/original/E328I09.png" width="800" height="495" alt="The list of products now looks much better with Twitter Bootstrap's CSS applied."/&gt;
&lt;/div&gt;

&lt;p&gt;Similar changes have been applied to the pages for viewing and editing a single product. We can view the source for these templates to see exactly how this works. &lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/products/index.html.erb&lt;/p&gt;
&amp;lt;h1&amp;gt;Products&amp;lt;/h1&amp;gt;
&amp;lt;table class=&amp;quot;table table-striped&amp;quot;&amp;gt;
  &amp;lt;thead&amp;gt;
    &amp;lt;tr&amp;gt;
      &amp;lt;th&amp;gt;ID&amp;lt;/th&amp;gt;
      &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;
      &amp;lt;th&amp;gt;Created at&amp;lt;/th&amp;gt;
      &amp;lt;th&amp;gt;Actions&amp;lt;/th&amp;gt;
    &amp;lt;/tr&amp;gt;
  &amp;lt;/thead&amp;gt;
  &amp;lt;tbody&amp;gt;
    &amp;lt;% @products.each do |product| %&amp;gt;
      &amp;lt;tr&amp;gt;
        &amp;lt;td&amp;gt;&amp;lt;%= product.id %&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;td&amp;gt;&amp;lt;%= link_to product.name, product_path(product) %&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;td&amp;gt;&amp;lt;%= product.created_at %&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;td&amp;gt;
          &amp;lt;%= link_to &amp;#x27;Edit&amp;#x27;, edit_product_path(product), :class =&amp;gt; &amp;#x27;btn btn-mini&amp;#x27; %&amp;gt;
          &amp;lt;%= link_to &amp;#x27;Destroy&amp;#x27;, product_path(product), :method =&amp;gt; :delete, :confirm =&amp;gt; &amp;#x27;Are you sure?&amp;#x27;, :class =&amp;gt; &amp;#x27;btn btn-mini btn-danger&amp;#x27; %&amp;gt;
        &amp;lt;/td&amp;gt;
      &amp;lt;/tr&amp;gt;
    &amp;lt;% end %&amp;gt;
  &amp;lt;/tbody&amp;gt;
&amp;lt;/table&amp;gt;

&amp;lt;%= link_to &amp;#x27;New&amp;#x27;, new_product_path, :class =&amp;gt; &amp;#x27;btn btn-primary&amp;#x27; %&amp;gt;
&lt;/pre&gt;

&lt;p&gt;A couple of CSS classes have been added to the table that displays the products. Similarly classes have been added to the &amp;ldquo;Edit&amp;rdquo; and &amp;ldquo;Destroy&amp;rdquo; links to improve their look. The biggest change has happened to the partial that contains the form for creating or editing a product.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/products/_form.html.erb&lt;/p&gt;
&amp;lt;%= form_for @product, :html =&amp;gt; { :class =&amp;gt; &amp;#x27;form-horizontal&amp;#x27; } do |f| %&amp;gt;
  &amp;lt;fieldset&amp;gt;
    &amp;lt;legend&amp;gt;&amp;lt;%= controller.action_name.capitalize %&amp;gt; Product&amp;lt;/legend&amp;gt;

    &amp;lt;div class=&amp;quot;control-group&amp;quot;&amp;gt;
      &amp;lt;%= f.label :name, :class =&amp;gt; &amp;#x27;control-label&amp;#x27; %&amp;gt;
      &amp;lt;div class=&amp;quot;controls&amp;quot;&amp;gt;
        &amp;lt;%= f.text_field :name, :class =&amp;gt; &amp;#x27;text_field&amp;#x27; %&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div class=&amp;quot;control-group&amp;quot;&amp;gt;
      &amp;lt;%= f.label :price, :class =&amp;gt; &amp;#x27;control-label&amp;#x27; %&amp;gt;
      &amp;lt;div class=&amp;quot;controls&amp;quot;&amp;gt;
        &amp;lt;%= f.text_field :price, :class =&amp;gt; &amp;#x27;text_field&amp;#x27; %&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div class=&amp;quot;form-actions&amp;quot;&amp;gt;
      &amp;lt;%= f.submit nil, :class =&amp;gt; &amp;#x27;btn btn-primary&amp;#x27; %&amp;gt;
      &amp;lt;%= link_to &amp;#x27;Cancel&amp;#x27;, products_path, :class =&amp;gt; &amp;#x27;btn&amp;#x27; %&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/fieldset&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;

&lt;p&gt;The code in here has changed significantly from the scaffolding code and it serves as a nice example as to how you can get a form to look really good with Twitter Bootstrap.&lt;/p&gt; 

&lt;p&gt;We&amp;rsquo;re nearing the end of this episode now and we said we&amp;rsquo;d mention some alternatives to the twitter-bootstrap-rails gem. There&amp;rsquo;s a list of these in &lt;a href="http://rubysource.com/twitter-bootstrap-less-and-sass-understanding-your-options-for-rails-3-1/"&gt;this article on Ruby Source&lt;/a&gt; which explains how Twitter Bootstrap works and shows the various options and gems that are available for integrating it with Rails.&lt;/p&gt;
</description>
      <pubDate>Sun, 04 Mar 2012 17:10:27 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/328-twitter-bootstrap-basics</guid>
      <link>http://asciicasts.com/episodes/328-twitter-bootstrap-basics</link>
    </item>
    <item>
      <title>ActiveAttr</title>
      <description>&lt;p&gt;Back in &lt;a href="http://railscasts.com/episodes/219-active-model"&gt;episode 219&lt;/a&gt; we used ActiveModel to create a model that isn&amp;rsquo;t backed by a database table but which still has some ActiveRecord features, such as validations. ActiveModel is great but isn&amp;rsquo;t very convenient to use directly like this. For example it takes quite a bit of code just to make a simple model that has some validation support.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/models/message.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
class Message
  include ActiveModel::Validations
  include ActiveModel::Conversion
  extend ActiveModel::Naming

  attr_accessor :name, :email, :content

  validates_presence_of :name
  validates_format_of :email, :with =&amp;gt; /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i
  validates_length_of :content, :maximum =&amp;gt; 500

  def initialize(attributes = {})
    attributes.each do |name, value|
      send(&amp;quot;#{name}=&amp;quot;, value)
    end
  end

  def persisted?
    false
  end
end
&lt;/pre&gt;

&lt;p&gt;There is a gem called &lt;a href="https://github.com/cgriego/active_attr"&gt;ActiveAttr&lt;/a&gt; that can help with this. It&amp;rsquo;s described by its author Chris Greigo as &amp;ldquo;what ActiveModel left out&amp;rdquo; which is a fair description of what it does. Using it makes it much easier to create a table-less model that behaves similarly to ActiveRecord and we&amp;rsquo;ll show you how it works in this episode.&lt;/p&gt;

&lt;h3&gt;Using ActiveAttr With a Contact Form&lt;/h3&gt;

&lt;p&gt;We&amp;rsquo;ll be working with an application which has a &amp;ldquo;Contact Us&amp;rdquo; form. When the form is filled in and submitted we want to send an email but not save the message to the database. We don&amp;rsquo;t want to use ActiveRecord at all here but we do want to use some of its features, such as validations, so that if the user fails to fill the form in correctly they see some error messages explaining what they&amp;rsquo;ve done wrong.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/1011/original/E326I01.png" width="800" height="464" alt="The contact form."/&gt;
&lt;/div&gt;

&lt;p&gt;We&amp;rsquo;ve already created the controller and view for this and they work very similarly to what we&amp;rsquo;d have if we used Rails&amp;rsquo; scaffolding. We&amp;rsquo;ll walk through it quickly now. The &lt;code&gt;MessagesController&lt;/code&gt; has &lt;code&gt;new&lt;/code&gt; and &lt;code&gt;create&lt;/code&gt; actions. When the new action is triggered it will create a new instance of &lt;code&gt;Message&lt;/code&gt; and render out a template.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/messages/new.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;lt;h1&amp;gt;Contact Us&amp;lt;/h1&amp;gt;

&amp;lt;%= form_for @message do |f| %&amp;gt;
  &amp;lt;% if @message.errors.any? %&amp;gt;
    &amp;lt;div class=&amp;quot;error_messages&amp;quot;&amp;gt;
      &amp;lt;h2&amp;gt;&amp;lt;%= pluralize(@message.errors.count, &amp;quot;error&amp;quot;) %&amp;gt; prohibited this message from being saved:&amp;lt;/h2&amp;gt;
      &amp;lt;ul&amp;gt;
      &amp;lt;% @message.errors.full_messages.each do |msg| %&amp;gt;
        &amp;lt;li&amp;gt;&amp;lt;%= msg %&amp;gt;&amp;lt;/li&amp;gt;
      &amp;lt;% end %&amp;gt;
      &amp;lt;/ul&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;% end %&amp;gt;
  &amp;lt;div class=&amp;quot;field&amp;quot;&amp;gt;
    &amp;lt;%= f.label :name %&amp;gt;&amp;lt;br /&amp;gt;
    &amp;lt;%= f.text_field :name %&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;field&amp;quot;&amp;gt;
    &amp;lt;%= f.label :email %&amp;gt;&amp;lt;br /&amp;gt;
    &amp;lt;%= f.text_field :email %&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;field&amp;quot;&amp;gt;
    &amp;lt;%= f.label :content, &amp;quot;Message&amp;quot; %&amp;gt;&amp;lt;br /&amp;gt;
    &amp;lt;%= f.text_area :content, :rows =&amp;gt; 5 %&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;actions&amp;quot;&amp;gt;&amp;lt;%= f.submit &amp;quot;Send Message&amp;quot; %&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/pre&gt;

&lt;p&gt;This view holds the code for the form. Note that we&amp;rsquo;re using &lt;code&gt;form_for&lt;/code&gt; to define the form and passing it the message model instance from the controller. We display error messages just as we would with scaffold-generated code so from the view template this looks just like code to handle an ActiveRecord model. When the form is submitted it triggers the controller&amp;rsquo;s &lt;code&gt;create&lt;/code&gt; action.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/controllers/messages_controller.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
class MessagesController &amp;lt; ApplicationController
  def new
    @message = Message.new
  end

  def create
    @message = Message.new(params[:message])
    if @message.valid?
      # TODO send message here
      redirect_to root_url, notice: &amp;quot;Message sent! Thank you for contacting us.&amp;quot;
    else
      render &amp;quot;new&amp;quot;
    end
  end
end
&lt;/pre&gt;

&lt;p&gt;This action makes a new &lt;code&gt;Message&lt;/code&gt; instance base based on the parameters from the form then checks that the new message is valid. If so it will email the message and redirect back to the home page. If it&amp;rsquo;s invalid it will render the form again. We need this message model to behave just like ActiveRecord, except that we&amp;rsquo;re just validating it not saving it to a database table.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Message&lt;/code&gt; model currently uses ActiveModel to handle this behaviour and you can see its code at the top of the this episode. We don&amp;rsquo;t want to use this approach here, though. Instead we&amp;rsquo;re going to use ActiveAttr. To do this we&amp;rsquo;ll need to add the gem to the gemfile and run &lt;code&gt;bundle&lt;/code&gt; to install it.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/Gemfile&lt;/p&gt;
&lt;pre class="ruby"&gt;
gem 'active_attr'
&lt;/pre&gt;

&lt;p&gt;We can now use ActiveAttr in our model.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/models/message.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
class Message
  include ActiveAttr::Model
end
&lt;/pre&gt;

&lt;p&gt;Note that &lt;code&gt;Message&lt;/code&gt; doesn&amp;rsquo;t inherit from another class, it&amp;rsquo;s just a simple Ruby class. By including &lt;code&gt;ActiveAttr::Model&lt;/code&gt; we&amp;rsquo;ll add some functionality that builds on ActiveModel to make this class behave more like an ActiveRecord model. We can define attributes for the model by using &lt;code&gt;attribute&lt;/code&gt; and we can add validations in the same way we would for an ActiveRecord-derived class.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/models/message.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
class Message
  include ActiveAttr::Model
  
  attribute :name
  attribute :email
  attribute :content
  
  validates_presence_of :name
  validates_format_of :email, :with =&amp;gt; /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i
  validates_length_of :content, :maximum =&amp;gt; 500
end
&lt;/pre&gt;

&lt;p&gt;We now have a fully-functional model that behaves like an ActiveRecord model. If we try visiting the form again and submit it without filling in any of the fields we&amp;rsquo;ll see validation errors just like we expect but the model code is quite a bit simpler.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/1012/original/E326I02.png" width="800" height="561" alt="If the form is filled in incorrectly the validation errors will be displayed."/&gt;
&lt;/div&gt;

&lt;h3&gt;Mass Assignment Protection&lt;/h3&gt;

&lt;p&gt;ActiveAttr also provides mass assignment protection. Let&amp;rsquo;s say that we have a priority attribute on the Message model and that we don&amp;rsquo;t want it to be settable through form values. We can use &lt;code&gt;attr_accessible&lt;/code&gt; to define the attributes that should be accessible just like we would with an ActiveRecord model.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/models/message.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
class Message
  include ActiveAttr::Model
  
  attribute :name
  attribute :email
  attribute :content
  attribute :priority
  
  attr_accessible :name, :email, :content

  validates_presence_of :name
  validates_format_of :email, :with =&amp;gt; /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i
  validates_length_of :content, :maximum =&amp;gt; 500
end
&lt;/pre&gt;

&lt;p&gt;We can test this behaviour in the console. If we create a new &lt;code&gt;Message&lt;/code&gt; and try to set its &lt;code&gt;priority&lt;/code&gt; this will fail, although we can set &lt;code&gt;priority&lt;/code&gt; directly.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;console&lt;/p&gt;
&lt;pre class="terminal"&gt;
1.9.3p0 :001 &amp;gt; m = Message.new(priority: 1)
 =&amp;gt; #&amp;lt;Message content: nil, email: nil, name: nil, priority: nil&amp;gt; 
1.9.3p0 :002 &amp;gt; m.priority
 =&amp;gt; nil 
1.9.3p0 :003 &amp;gt; m.priority = 1
 =&amp;gt; 1
&lt;/pre&gt;
 
&lt;p&gt;ActiveAttr also allows us to call an attribute with a question mark to force its value to be boolean just like ActiveRecord does. Future versions of ActiveAttr will also allow us to pass additional options to &lt;code&gt;attribute&lt;/code&gt; so that we can specify the attribute&amp;rsquo;s type and also a default value.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/models/message.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
 attribute :priority, type: Integer, default: 0
&lt;/pre&gt;

&lt;p&gt;These options aren&amp;rsquo;t yet available but they should be coming soon so it&amp;rsquo;s worth checking ActiveAttr&amp;rsquo;s Github page so see if these features have been released.&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s it for this episode on ActiveAttr. It&amp;rsquo;s a great way to make table-less models. The documentation has further details of what you can do with it. We&amp;rsquo;ve used the &lt;code&gt;ActiveAttr::Model&lt;/code&gt; module which includes everything but there are separate modules for its different features which can be used if you only need part of ActiveAttr&amp;rsquo;s functionality.&lt;/p&gt;</description>
      <pubDate>Sat, 25 Feb 2012 20:00:46 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/326-activeattr</guid>
      <link>http://asciicasts.com/episodes/326-activeattr</link>
    </item>
    <item>
      <title>Passing Data to JavaScript</title>
      <description>&lt;p&gt;When JavaScript plays a large part in a Rails application it often becomes necessary to pass data from the app on the server to JavaScript to be used by the client. In this episode we&amp;rsquo;ll explore some techniques for doing just that. Below is a simple page from a simple Rails application. The idea here is that we want JavaScript to take over and handle fetching and displaying the products. To do that we&amp;rsquo;ll need to pass some information from our app to the JavaScript that runs on the client.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/992/original/E324I01.png" width="800" height="280" alt="The products page."/&gt;
&lt;/div&gt;

&lt;p&gt;The view template for this page is simple as the page suggests.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/products/index.html.erb&lt;/p&gt;
&lt;pre class="html"&gt;&amp;lt;h1&amp;gt;Products&amp;lt;/h1&amp;gt;

&amp;lt;div id=&amp;quot;products&amp;quot;&amp;gt;
  Loading products...
&amp;lt;/div&amp;gt;&lt;/pre&gt;

&lt;p&gt;Let&amp;rsquo;s say that the JavaScript in the app needs to know the URL to call to fetch the list of products. We don&amp;rsquo;t want to hard-code this in the JavaScript code and so we&amp;rsquo;ll generate it dynamically in our Rails app. One way we can do this is to use &lt;code&gt;javascript_tag&lt;/code&gt; in the view.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/products/index.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;%= javascript_tag do %&amp;gt;
  window.productsURL = &amp;#x27;&amp;lt;%= j products_url %&amp;gt;&amp;#x27;;
&amp;lt;% end %&amp;gt;&lt;/pre&gt;

&lt;p&gt;Note that we use Rails&amp;rsquo; &lt;code&gt;j&lt;/code&gt; method to make sure that the URL is safely escaped for embedding in JavaScript. Now we can use this variable in any of the JavaScript or CoffeeScript files that this page references.&lt;/p&gt;

&lt;p class="codeFilePath"&gt; /app/assets/javascripts/products.js.coffee&lt;/p&gt;
&lt;pre class="javascript"&gt;jQuery -&gt;
  alert productsURL&lt;/pre&gt;

&lt;p&gt;If we want to preload the page with an initial set of products instead of having fetch them in a separate request we could fetch, say, the first ten products as JSON and have the JavaScript display them straight away. We could do this by writing something like this:&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/products/index.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;%= javascript_tag do %&amp;gt;
  window.productsURL = &amp;#x27;&amp;lt;%= j products_url %&amp;gt;&amp;#x27;;
  window.products = &amp;lt;%= raw Product.limit(10).to_json %&amp;gt;
&amp;lt;% end %&amp;gt;&lt;/pre&gt;

&lt;p&gt;Rails will automatically try to HTML-escape the list of products and so we have to call raw on the JSON that&amp;rsquo;s returned.&lt;/p&gt;

&lt;p&gt;This approach can become awkward fairly quickly and using data attributes on HTML can often be a better alternative. We can  pass in the products URL to one like this:&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/products/index.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;h1&amp;gt;Products&amp;lt;/h1&amp;gt;

&amp;lt;div id=&amp;quot;products&amp;quot; data-url=&amp;quot;&amp;lt;%= products_url %&amp;gt;&amp;quot;&amp;gt;
  Loading products...
&amp;lt;/div&amp;gt;&lt;/pre&gt;

We can easily fetch this information with some jQuery code.

&lt;p class="codeFilePath"&gt;/app/assets/javascripts/products.js.coffee&lt;/p&gt;
&lt;pre class="javascript"&gt;jQuery -&gt;
  alert $('#products').data('url')&lt;/pre&gt;

&lt;p&gt;This technique has the same effect but feels a little cleaner, apart from having to nest Erb tags within HTML attributes. Using &lt;code&gt;content_tag&lt;/code&gt; is generally a better approach for inserting dynamic data into an HTML tag.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/products/index.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;h1&amp;gt;Products&amp;lt;/h1&amp;gt;

&amp;lt;%= content_tag &amp;quot;div&amp;quot;, id: &amp;quot;products&amp;quot;, data: {url: products_url} do %&amp;gt;
  Loading products...
&amp;lt;% end %&amp;gt;&lt;/pre&gt;

&lt;p&gt;Since Rails 3.1 we&amp;rsquo;ve been able to use a &lt;code&gt;data&lt;/code&gt; hash to define data attributes which makes this approach even better. If we pass Ruby objects into this hash &lt;code&gt;to_json&lt;/code&gt; is called so that the object or objects passed in are automatically converted to their JSON representation.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/products/index.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;h1&amp;gt;Products&amp;lt;/h1&amp;gt;

&amp;lt;%= content_tag &amp;quot;div&amp;quot;, id: &amp;quot;products&amp;quot;, data: {url: Product.limit(10) } do %&amp;gt;
  Loading products...
&amp;lt;% end %&amp;gt;&lt;/pre&gt;

&lt;p&gt;When we fetch this data it will be automatically parsed into a JavaScript object. &lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/javascripts/products.js.coffee&lt;/p&gt;
&lt;pre class="javascript"&gt;jQuery -&amp;gt;
  console.log $(&amp;#x27;#products&amp;#x27;).data(&amp;#x27;url&amp;#x27;)&lt;/pre&gt;  

&lt;p&gt;If we reload the page now we&amp;rsquo;ll see the products listed in the console.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/993/original/E324I02.png" width="801" height="400" alt="The JSON representation of the products shown in the console."/&gt;
&lt;/div&gt;

&lt;h3&gt;Gon&lt;/h3&gt;

&lt;p&gt;If we have a lot of data to pass to the JavaScript this technique can still become fairly cumbersome. Fortunately there&amp;rsquo;s one more solution we can use: &lt;a href="https://github.com/gazay/gon"&gt;the Gon gem&lt;/a&gt;. This allows us to set variables in our controllers and then access them from JavaScript. Gon is installed in the usual way, by adding it to the gemfile and running &lt;code&gt;bundle&lt;/code&gt;.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/Gemfile&lt;/p&gt;
&lt;pre class="ruby"&gt;source &amp;#x27;https://rubygems.org&amp;#x27;

gem &amp;#x27;rails&amp;#x27;, &amp;#x27;3.2.1&amp;#x27;
gem &amp;#x27;sqlite3&amp;#x27;

# Gems used only for assets and not required
# in production environments by default.
group :assets do
  gem &amp;#x27;sass-rails&amp;#x27;,   &amp;#x27;~&amp;gt; 3.2.3&amp;#x27;
  gem &amp;#x27;coffee-rails&amp;#x27;, &amp;#x27;~&amp;gt; 3.2.1&amp;#x27;

  # See https://github.com/sstephenson/execjs#readme for more supported runtimes
  # gem &amp;#x27;therubyracer&amp;#x27;

  gem &amp;#x27;uglifier&amp;#x27;, &amp;#x27;&amp;gt;= 1.0.3&amp;#x27;
end

gem &amp;#x27;jquery-rails&amp;#x27;
gem &amp;#x27;gon&amp;#x27;&lt;/pre&gt;


&lt;p&gt;Next we&amp;rsquo;ll need to update our application&amp;rsquo;s layout file by adding &lt;code&gt;include_gon&lt;/code&gt; somewhere inside the &lt;code&gt;head&lt;/code&gt; section.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/layouts/application.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;Store&amp;lt;/title&amp;gt;
  &amp;lt;%= include_gon %&amp;gt;
  &amp;lt;%= stylesheet_link_tag    &amp;quot;application&amp;quot;, media: &amp;quot;all&amp;quot; %&amp;gt;
  &amp;lt;%= javascript_include_tag &amp;quot;application&amp;quot; %&amp;gt;
  &amp;lt;%= csrf_meta_tag %&amp;gt;
&amp;lt;/head&amp;gt;&lt;/pre&gt;

&lt;p&gt;If we do this before we load any other JavaScript files we&amp;rsquo;ll be able to access the variables we&amp;rsquo;ve set through Gon without waiting for the entire DOM to load.&lt;/p&gt;

&lt;p&gt;We can now set variables on a &lt;code&gt;gon&lt;/code&gt; object in a controller action.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/controllers/products_controller.rb&lt;/p&gt;

&lt;pre class="ruby"&gt;class ProductsController &amp;lt; ApplicationController
  def index
    gon.products = Product.limit(10)
  end
end&lt;/pre&gt;

&lt;p&gt;This list of products will now automatically be converted to JSON and be accessible by our application&amp;rsquo;s JavaScript. We can access this list of products like this:&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/javascripts/products.js.coffee&lt;/p&gt;
&lt;pre class="javascript"&gt;console.log gon.products&lt;/pre&gt;

&lt;p&gt;Note that we don&amp;rsquo;t have to wait for the DOM to load before we access this data. If we reload the page now we&amp;rsquo;ll see the list of products in the console again.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/994/original/E324I03.png" width="801" height="400" alt="The JSON representation of the products from Gon shown in the console."/&gt;
&lt;/div&gt;

&lt;p&gt;If we view the page&amp;rsquo;s source we&amp;rsquo;ll see how this all works.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;html&lt;/p&gt;
&lt;pre class="html"&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Store&amp;lt;/title&amp;gt;
	&amp;lt;script&amp;gt;window.gon = {};gon.products=[{&amp;quot;created_at&amp;quot;:&amp;quot;2012-02-18T20:24:45Z&amp;quot;,&amp;quot;id&amp;quot;:1,&amp;quot;name&amp;quot;:&amp;quot;Settlers of Catan&amp;quot;,&amp;quot;price&amp;quot;:&amp;quot;29.95&amp;quot;,&amp;quot;updated_at&amp;quot;:&amp;quot;2012-02-18T20:24:45Z&amp;quot;},{&amp;quot;created_at&amp;quot;:&amp;quot;2012-02-18T20:24:45Z&amp;quot;,&amp;quot;id&amp;quot;:2,&amp;quot;name&amp;quot;:&amp;quot;DVD Player&amp;quot;,&amp;quot;price&amp;quot;:&amp;quot;79.98999999999999&amp;quot;,&amp;quot;updated_at&amp;quot;:&amp;quot;2012-02-18T20:24:45Z&amp;quot;},{&amp;quot;created_at&amp;quot;:&amp;quot;2012-02-18T20:24:45Z&amp;quot;,&amp;quot;id&amp;quot;:3,&amp;quot;name&amp;quot;:&amp;quot;Red Shirt&amp;quot;,&amp;quot;price&amp;quot;:&amp;quot;12.49&amp;quot;,&amp;quot;updated_at&amp;quot;:&amp;quot;2012-02-18T20:24:45Z&amp;quot;}];&amp;lt;/script&amp;gt;
    // Other products omitted.
    &amp;lt;link href=&amp;quot;/assets/application.css?body=1&amp;quot; media=&amp;quot;all&amp;quot; rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; /&amp;gt;
&amp;lt;link href=&amp;quot;/assets/products.css?body=1&amp;quot; media=&amp;quot;all&amp;quot; rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; /&amp;gt;
    &amp;lt;script src=&amp;quot;/assets/jquery.js?body=1&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&amp;quot;/assets/jquery_ujs.js?body=1&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&amp;quot;/assets/products.js?body=1&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&amp;quot;/assets/application.js?body=1&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;meta content=&amp;quot;authenticity_token&amp;quot; name=&amp;quot;csrf-param&amp;quot; /&amp;gt;
&amp;lt;meta content=&amp;quot;KktOQAWKvaRho+IdWOiaBud0W7Vuv31rdn0LF38hBag=&amp;quot; name=&amp;quot;csrf-token&amp;quot; /&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;!-- Body omitted --&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/pre&gt;

&lt;p&gt;Gon simply creates a &lt;code&gt;script&lt;/code&gt; tag then fills a &lt;code&gt;gon&lt;/code&gt; variable with the data that we set in the controller. If we want to customize the JSON that&amp;rsquo;s returned to the client Gon has support for both RABL and Jbuilder templates, both of which have been covered in recent episodes. To customize the data returned by the list of products we can create an &lt;code&gt;index.json.rabl&lt;/code&gt; file and define the attributes we want to be returned there.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/products/index.json.rabl&lt;/p&gt;
&lt;pre class="ruby"&gt;collection Product.limit(10)

attributes :id, :name, :price&lt;/pre&gt;

&lt;p&gt;We can use &lt;code&gt;gon.rabl&lt;/code&gt; to tell Gon to use this template. &lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/controllers/products_controller.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;class ProductsController &amp;lt; ApplicationController
  def index
    gon.rabl &amp;quot;app/views/products/index.json.rabl&amp;quot;, as: &amp;quot;products&amp;quot;
  end
end&lt;/pre&gt;

&lt;p&gt;This will store the response from the template in a &lt;code&gt;products&lt;/code&gt; variable. When we reload the page now we&amp;rsquo;ll see the same list of products, but their attributes will have been defined by the RABL template.&lt;/p&gt;

&lt;p&gt;There&amp;rsquo;s a small potential trap when using Gon. If we don&amp;rsquo;t define any &lt;code&gt;gon&lt;/code&gt; variables in a controller action and we try to call &lt;code&gt;gon&lt;/code&gt; in the JavaScript we&amp;rsquo;ll get an error as the &lt;code&gt;gon&lt;/code&gt; object won&amp;rsquo;t have been set. It&amp;rsquo;s always best to ensure that this object exists before trying to call anything against it.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/javascripts/products.js.coffee&lt;/p&gt;
&lt;pre class="javascript"&gt;console.log gon.products if gon&lt;/pre&gt;

&lt;p&gt;There&amp;rsquo;s more information about Gon in its &lt;a href="https://github.com/gazay/gon/blob/master/README.md"&gt;documentation&lt;/a&gt; which is well worth reading if you&amp;rsquo;re thinking of using it in your Rails applications.&lt;/p&gt;</description>
      <pubDate>Sun, 19 Feb 2012 18:34:51 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/324-passing-data-to-javascript</guid>
      <link>http://asciicasts.com/episodes/324-passing-data-to-javascript</link>
    </item>
    <item>
      <title>OmniAuth Identity</title>
      <description>&lt;p&gt;&lt;a href="http://www.omniauth.org/"&gt;OmniAuth&lt;/a&gt; recently reached version 1.0 and has a number of nice additions. In this episode we&amp;rsquo;ll take a look at a new strategy called OmniAuth Identity which allows users to create an account by supplying a user name and password instead of logging in through an external provider.&lt;/p&gt;

&lt;h3&gt;How Our Application Currently Works&lt;/h3&gt;

&lt;p&gt;Below is a screenshot from the application we&amp;rsquo;ll be working with. We already have OmniAuth set up with three external providers.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/874/original/E304I01.png" width="800" height="341" alt="Our application currently only allows signing-in through an external provider."/&gt;
&lt;/div&gt;

&lt;p&gt;If we sign in through one of these providers, say Twitter, we&amp;rsquo;ll be redirected to Twitter&amp;rsquo;s website and asked if we want to authorize the application to access our Twitter account details. If we agree the application will grab our profile information from Twitter and we&amp;rsquo;ll be signed in.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/875/original/E304I02.png" width="800" height="379" alt="Profile information from the external provider is shown once we've logged in."/&gt;
&lt;/div&gt;

&lt;p&gt;Once we&amp;rsquo;ve authorized this application we won&amp;rsquo;t need to do it again and we can log in to our application through Twitter by just clicking the icon on the home page.&lt;/p&gt;

&lt;p&gt;This is a convenient way of allowing users to sign in to but we&amp;rsquo;re excluding those who don&amp;rsquo;t want to sign in through one of these services. We should give these users the option of creating an account with a password directly in the site and this is where OmniAuth Identity comes in.&lt;/p&gt;

&lt;p&gt;Before we do this we&amp;rsquo;ll walk through some of the application&amp;rsquo;s code to give you an idea of how it works. The source code is based on the application from &lt;a href="http://railscasts.com/episodes/241-simple-omniauth"&gt;episode 241&lt;/a&gt; and if you&amp;rsquo;re unfamiliar with OmniAuth it&amp;rsquo;s worth taking a look at that episode first.&lt;/p&gt; 

&lt;p&gt;Since episode 241 was written there have been some changes to OmniAuth and one of the most significant is in the gemfile. Each provider now has a separate gem for OmniAuth so it&amp;rsquo;s necessary to include the right gem for each provider we want to support.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/Gemfile&lt;/p&gt;
&lt;pre class="ruby"&gt;gem &amp;#x27;omniauth-twitter&amp;#x27;
gem &amp;#x27;omniauth-facebook&amp;#x27;
gem &amp;#x27;omniauth-google-oauth2&amp;#x27;&lt;/pre&gt;

&lt;p&gt;OmniAuth&amp;rsquo;s initializer looks much the same as it did before. In it we add OmniAuth as middleware and add a provider for each provider we want to use.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/config/initializers/omniauth.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;Rails.application.config.middleware.use OmniAuth::Builder do
  provider :twitter, ENV[&amp;#x27;TWITTER_KEY&amp;#x27;], ENV[&amp;#x27;TWITTER_SECRET&amp;#x27;]
  provider :google_oauth2, ENV[&amp;#x27;GOOGLE_KEY&amp;#x27;], ENV[&amp;#x27;GOOGLE_SECRET&amp;#x27;]
  provider :facebook, ENV[&amp;#x27;FACEBOOK_ID&amp;#x27;], ENV[&amp;#x27;FACEBOOK_SECRET&amp;#x27;]
end&lt;/pre&gt;

&lt;p&gt;The application has a &lt;code&gt;SessionsController&lt;/code&gt; whose create action is triggered as the OmniAuth callback. In it we create a user based on the OmniAuth hash and store that new user&amp;rsquo;s &lt;code&gt;id&lt;/code&gt; in a session variable.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/controllers/sessions_controller.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;class SessionsController &amp;lt; ApplicationController
  def new
  end

  def create
    user = User.from_omniauth(env[&amp;quot;omniauth.auth&amp;quot;])
    session[:user_id] = user.id
    redirect_to root_url, notice: &amp;quot;Signed in!&amp;quot;
  end

  def destroy
    session[:user_id] = nil
    redirect_to root_url, notice: &amp;quot;Signed out!&amp;quot;
  end

  def failure
    redirect_to root_url, alert: &amp;quot;Authentication failed, please try again.&amp;quot;
  end
end&lt;/pre&gt;

&lt;p&gt;The user is fetched from OmniAuth in a &lt;code&gt;from_omniauth&lt;/code&gt; method in the &lt;code&gt;User&lt;/code&gt; model.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/models/user.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;class User &amp;lt; ActiveRecord::Base
  def self.from_omniauth(auth)
    find_by_provider_and_uid(auth[&amp;quot;provider&amp;quot;], auth[&amp;quot;uid&amp;quot;]) || create_with_omniauth(auth)
  end

  def self.create_with_omniauth(auth)
    create! do |user|
      user.provider = auth[&amp;quot;provider&amp;quot;]
      user.uid = auth[&amp;quot;uid&amp;quot;]
      user.name = auth[&amp;quot;info&amp;quot;][&amp;quot;name&amp;quot;]
    end
  end
end&lt;/pre&gt;

&lt;p&gt;This method first checks to see if a user with the selected provider and user id exists. If so that user is returned, if not a &lt;code&gt;create_with_omniauth&lt;/code&gt; method is called which creates that new user based on information from the OmniAuth hash that&amp;rsquo;s passed in. There&amp;rsquo;s one change to note in the hash. The &lt;code&gt;info&lt;/code&gt; parameter was called &lt;code&gt;user_info&lt;/code&gt; in earlier versions so if you&amp;rsquo;re upgrading an application to use OmniAuth 1.0 your code may break.&lt;/p&gt;

&lt;h3&gt;Adding OmniAuth Identity to an Application&lt;/h3&gt;

&lt;p&gt;That&amp;rsquo;s all the code that&amp;rsquo;s necessary to handle authentication through OmniAuth. Next we&amp;rsquo;ll add OmniAuth Identity so that users can create an account without having to use an external authentication service. As we mentioned earlier each OmniAuth provider requires a separate gem so the first thing we&amp;rsquo;ll need to do is add the &lt;code&gt;omniauth-identity&lt;/code&gt; gem to the gemfile.&lt;/p&gt; 

&lt;p class="codeFilePath"&gt;/Gemfile&lt;/p&gt;
&lt;pre class="ruby"&gt;# To use ActiveModel has_secure_password
gem &amp;#x27;bcrypt-ruby&amp;#x27;, &amp;#x27;~&amp;gt; 3.0.0&amp;#x27;

gem &amp;#x27;omniauth-twitter&amp;#x27;
gem &amp;#x27;omniauth-facebook&amp;#x27;
gem &amp;#x27;omniauth-google-oauth2&amp;#x27;
gem &amp;#x27;omniauth-identity&amp;#x27;&lt;/pre&gt;

&lt;p&gt;This gem relies on &lt;code&gt;bcrypt-ruby&lt;/code&gt; for password hashing, but it&amp;rsquo;s not a dependency so it&amp;rsquo;s necessary to add &lt;code&gt;bcrypt-ruby&lt;/code&gt; to the gemfile as well. There should be a comment in the gemfile that we can uncomment to add this gem. As ever we&amp;rsquo;ll need to run bundle to make sure all the gems are installed.&lt;/p&gt;

&lt;p&gt;Next we&amp;rsquo;ll need to go to OmniAuth&amp;rsquo;s initializer and add the identity provider. We don&amp;rsquo;t need to add any parameters to this provider for now.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/config/initializers/omniauth.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;Rails.application.config.middleware.use OmniAuth::Builder do
  provider :twitter, ENV[&amp;#x27;TWITTER_KEY&amp;#x27;], ENV[&amp;#x27;TWITTER_SECRET&amp;#x27;]
  provider :google_oauth2, ENV[&amp;#x27;GOOGLE_KEY&amp;#x27;], ENV[&amp;#x27;GOOGLE_SECRET&amp;#x27;]
  provider :facebook, ENV[&amp;#x27;FACEBOOK_ID&amp;#x27;], ENV[&amp;#x27;FACEBOOK_SECRET&amp;#x27;]
  provider :identity
end&lt;/pre&gt;

&lt;p&gt;We&amp;rsquo;ll need a model to store login information. By default this model should be called &lt;code&gt;identity&lt;/code&gt;, but we can customize this if we need to. We&amp;rsquo;ll need to give it &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt; and &lt;code&gt;password_digest&lt;/code&gt; fields.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ rails g model identity name:string email:string password_digest:string&lt;/pre&gt;

&lt;p&gt;We&amp;rsquo;ll need to migrate the database to add the table.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ rake db:migrate&lt;/pre&gt;

&lt;p&gt;OmniAuth Identity&amp;rsquo;s &lt;a href="https://github.com/intridea/omniauth-identity/blob/master/README.markdown"&gt;README&lt;/a&gt; shows us what we need to do to get the Identity model to work with various ORMs, including ActiveRecord. We&amp;rsquo;ll need to change the model so that it inherits from &lt;code&gt;OmniAuth::Identity::Models::ActiveRecord&lt;/code&gt; instead of &lt;code&gt;ActiveRecord::Base&lt;/code&gt;.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/models/identity.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;class Identity &amp;lt; OmniAuth::Identity::Models::ActiveRecord
end&lt;/pre&gt;

&lt;p&gt;We&amp;rsquo;re almost done. All we need to do now is make a link to the new provider from the sign in page under the links for logging in through an external provider.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/sessions/new.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;p&amp;gt;
  &amp;lt;strong&amp;gt;Don&amp;amp;rsquo;t use these services?&amp;lt;/strong&amp;gt;
  &amp;lt;%= link_to &amp;quot;Create an account&amp;quot;, &amp;quot;/auth/identity/register&amp;quot; %&amp;gt; or
  &amp;lt;%= link_to &amp;quot;login&amp;quot;, &amp;quot;/auth/identity&amp;quot; %&amp;gt; with a password.
&amp;lt;/p&amp;gt;&lt;/pre&gt;

&lt;p&gt;We need to restart the server for the changes to OmniAuth to be picked up. Once we have when we visit the sign-in page we&amp;rsquo;ll see new links for registering or logging in. First we&amp;rsquo;ll register a new account.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/876/original/E304I03.png" width="800" height="555" alt="OmniAuth's registration form."/&gt;
&lt;/div&gt;

&lt;p&gt;OmniAuth Identity provides a simple registration form with a clean interface and once we&amp;rsquo;ve filled it in correctly we&amp;rsquo;ll be signed in and taken to our profile page.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/877/original/E304I04.png" width="800" height="382" alt="Signed in successfully through OmniAuth."/&gt;
&lt;/div&gt;

&lt;p&gt;The login page looks similar, but has just two fields. The login field expects the email address we entered when we registered, though this isn&amp;rsquo;t obvious.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/878/original/E304I05.png?" width="800" height="439" alt="OmniAuth&amp;rsquo;s login form."/&gt;
&lt;/div&gt;

&lt;h3&gt;Creating Custom Registration and Login Forms&lt;/h3&gt;

&lt;p&gt;Registration and logging-in pretty much just work and because Identity uses the same OmniAuth interface as the code for the other providers we don&amp;rsquo;t have to change much of our core application to add this functionality. That said, there are a few pitfalls we should be aware of. If we have validations on our &lt;code&gt;Identity&lt;/code&gt; model the user won&amp;rsquo;t see any errors if they fill in the form incorrectly. To demonstrate this we&amp;rsquo;ll add some validations to the &lt;code&gt;Identity&lt;/code&gt; model now.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/models/identity.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;class Identity &amp;lt; OmniAuth::Identity::Models::ActiveRecord
  validates_presence_of :name
  validates_uniqueness_of :email
  validates_format_of :email, :with =&amp;gt; /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i
end&lt;/pre&gt;

&lt;p&gt;If we enter an invalid email address on the registration form now and try to register we&amp;rsquo;ll be taken back to the form with no indication of what we did wrong.&lt;/p&gt;

&lt;p&gt;Similarly, the login form doesn&amp;rsquo;t make it clear that the &amp;ldquo;Login&amp;rdquo; field expects the user&amp;rsquo;s email address.  There are options to customize the way this form looks but nothing particularly extensive. A better solution is to create our own custom forms in to the app itself to give us complete control over how they&amp;rsquo;re rendered and how they behave.&lt;/p&gt;

&lt;p&gt;We&amp;rsquo;ll move the login form first. Instead of displaying a link to OmniAuth&amp;rsquo;s login form on the sign-in page we&amp;rsquo;ll show our custom login form.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/sessions/new.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;p&amp;gt;
  &amp;lt;strong&amp;gt;Don&amp;amp;rsquo;t use these services?&amp;lt;/strong&amp;gt;
  &amp;lt;%= link_to &amp;quot;Create an account&amp;quot;, &amp;quot;/auth/identity/register&amp;quot; %&amp;gt; or login below.
&amp;lt;/p&amp;gt;
  
&amp;lt;%= form_tag &amp;quot;/auth/identity/callback&amp;quot; do %&amp;gt;
  &amp;lt;div class=&amp;quot;field&amp;quot;&amp;gt;
    &amp;lt;%= label_tag :auth_key, &amp;quot;Email&amp;quot; %&amp;gt;&amp;lt;br&amp;gt;
    &amp;lt;%= text_field_tag :auth_key %&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;field&amp;quot;&amp;gt;
    &amp;lt;%= label_tag :password %&amp;gt;&amp;lt;br&amp;gt;
    &amp;lt;%= password_field_tag :password %&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;actions&amp;quot;&amp;gt;&amp;lt;%= submit_tag &amp;quot;Login&amp;quot; %&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;% end %&amp;gt;&lt;/pre&gt;

&lt;p&gt;This form POSTs to &lt;code&gt;/auth/identity/callback&lt;/code&gt; which is where OmniAuth&amp;rsquo;s own form submits its data. We also give the form fields the same names they have on OmniAuth&amp;rsquo;s form. When we reload the sign in page now we have a login form and we can use it to enter our details and log in to the site just as we did with the other form.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/879/original/E304I06.png" width="800" height="516" alt="Signing in through our custom form."/&gt;
&lt;/div&gt;

&lt;p&gt;We can take a similar approach to replacing the registration form, although we&amp;rsquo;ll need to create a new controller to do this.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ rails g controller identities&lt;/pre&gt;

&lt;p&gt;We&amp;rsquo;ll treat this controller as a resource so we&amp;rsquo;ll modify the routes file to add it as such there.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/config/routes.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;Auth::Application.routes.draw do
  root to: &amp;quot;sessions#new&amp;quot;
  match &amp;quot;/auth/:provider/callback&amp;quot;, to: &amp;quot;sessions#create&amp;quot;
  match &amp;quot;/auth/failure&amp;quot;, to: &amp;quot;sessions#failure&amp;quot;
  match &amp;quot;/logout&amp;quot;, to: &amp;quot;sessions#destroy&amp;quot;, :as =&amp;gt; &amp;quot;logout&amp;quot;
  resources :identities
end&lt;/pre&gt;

&lt;p&gt;We&amp;rsquo;ll give the controller a &lt;code&gt;new&lt;/code&gt; action. There&amp;rsquo;s a chance that if the validation for the registration form fails the &lt;code&gt;identity&lt;/code&gt; object will be stored in a Rack environment variable so we&amp;rsquo;ll fetch it from there so that we can show any error messages on it.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/controllers/identities_controller.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;class IdentitiesController &amp;lt; ApplicationController
  def new
    @identity = env[&amp;#x27;omniauth.identity&amp;#x27;]
  end
end&lt;/pre&gt;

&lt;p&gt;The associated template is fairly large but there&amp;rsquo;s nothing unusual in it.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;app/views/identities/new.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;h1&amp;gt;New Account&amp;lt;/h1&amp;gt;

&amp;lt;%= form_tag &amp;quot;/auth/identity/register&amp;quot; do %&amp;gt;
  &amp;lt;% if @identity &amp;amp;&amp;amp; @identity.errors.any? %&amp;gt;
    &amp;lt;div class=&amp;quot;error_messages&amp;quot;&amp;gt;
      &amp;lt;h2&amp;gt;&amp;lt;%= pluralize(@identity.errors.count, &amp;quot;error&amp;quot;) %&amp;gt; prohibited this account from being saved:&amp;lt;/h2&amp;gt;
      &amp;lt;ul&amp;gt;
      &amp;lt;% @identity.errors.full_messages.each do |msg| %&amp;gt;
        &amp;lt;li&amp;gt;&amp;lt;%= msg %&amp;gt;&amp;lt;/li&amp;gt;
      &amp;lt;% end %&amp;gt;
      &amp;lt;/ul&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;% end %&amp;gt;
  &amp;lt;div class=&amp;quot;field&amp;quot;&amp;gt;
    &amp;lt;%= label_tag :name %&amp;gt;&amp;lt;br&amp;gt;
    &amp;lt;%= text_field_tag :name, @identity.try(:name) %&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;field&amp;quot;&amp;gt;
    &amp;lt;%= label_tag :email %&amp;gt;&amp;lt;br&amp;gt;
    &amp;lt;%= text_field_tag :email, @identity.try(:email) %&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;field&amp;quot;&amp;gt;
    &amp;lt;%= label_tag :password %&amp;gt;&amp;lt;br&amp;gt;
    &amp;lt;%= password_field_tag :password %&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;field&amp;quot;&amp;gt;
    &amp;lt;%= label_tag :password_confirmation %&amp;gt;&amp;lt;br&amp;gt;
    &amp;lt;%= password_field_tag :password_confirmation %&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;actions&amp;quot;&amp;gt;&amp;lt;%= submit_tag &amp;quot;Register&amp;quot; %&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;% end %&amp;gt;&lt;/pre&gt;

&lt;p&gt;The form in this template POSTs to &lt;code&gt;/auth/identity/register&lt;/code&gt;. At the top of the form we display any errors; below it are the same fields that OmniAuth&amp;rsquo;s registration form has. We populate the name and email fields if they exist in the current &lt;code&gt;identity&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;We&amp;rsquo;ll need to alter the &amp;ldquo;Create an account&amp;rdquo; link on the sign in page so that it points to our new form instead of OmniAuth&amp;rsquo;s default.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/sessions/new.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;p&amp;gt;
  &amp;lt;strong&amp;gt;Don&amp;amp;rsquo;t use these services?&amp;lt;/strong&amp;gt;
  &amp;lt;%= link_to &amp;quot;Create an account&amp;quot;, new_identity_path %&amp;gt; or login below.
&amp;lt;/p&amp;gt;&lt;/pre&gt;

&lt;p&gt;When we click this link now we&amp;rsquo;ll be taken to our new form and we can use it to register a new account.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/880/original/E304I07.png" width="800" height="457" alt="Our new registration form."/&gt;
&lt;/div&gt;

&lt;p&gt;Our new form works well for creating new valid accounts but if we enter some invalid information then submit the form we&amp;rsquo;ll be redirected back to OmniAuth&amp;rsquo;s registration form. To fix this we&amp;rsquo;ll need to go to OmniAuth&amp;rsquo;s initializer file and modify the &lt;code&gt;identity&lt;/code&gt; provider we added earlier.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/config/initializers/omniauth.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;Rails.application.config.middleware.use OmniAuth::Builder do
  provider :twitter, ENV[&amp;#x27;TWITTER_KEY&amp;#x27;], ENV[&amp;#x27;TWITTER_SECRET&amp;#x27;]
  provider :google_oauth2, ENV[&amp;#x27;GOOGLE_KEY&amp;#x27;], ENV[&amp;#x27;GOOGLE_SECRET&amp;#x27;]
  provider :facebook, ENV[&amp;#x27;FACEBOOK_ID&amp;#x27;], ENV[&amp;#x27;FACEBOOK_SECRET&amp;#x27;]
  provider :identity, on_failed_registration: lambda { |env|    
    IdentitiesController.action(:new).call(env)
  }
end&lt;/pre&gt;

&lt;p&gt;The option we&amp;rsquo;ve added, &lt;code&gt;on_failed_registration&lt;/code&gt;, takes a Rack application as an argument. We&amp;rsquo;ve set it to point to the new action in the &lt;code&gt;IdentitiesController&lt;/code&gt; so that our new form is shown again. There&amp;rsquo;s an issue with calling this action directly: in development mode the action won&amp;rsquo;t always be reloaded so we&amp;rsquo;ve wrapped the code in a lambda to stop the action being cached.&lt;/p&gt; 

&lt;p&gt;We&amp;rsquo;ll need to start the Rails server for these changes to be picked up, but once we have the form will behave as we expect it to when we enter invalid information.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/881/original/E304I08.png" width="800" height="457" alt="Our registration form shows validation errors correctly."/&gt;
&lt;/div&gt;

&lt;p&gt;We now have OmniAuth identity working smoothly. Creating the custom forms took quite a bit of work but this is a still a nice solution if you&amp;rsquo;re already using OmniAuth and just need to add account registration.&lt;/p&gt;
</description>
      <pubDate>Sun, 29 Jan 2012 18:04:39 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/304-omniauth-identity</guid>
      <link>http://asciicasts.com/episodes/304-omniauth-identity</link>
    </item>
    <item>
      <title>In-place Editing</title>
      <description>&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/858/original/E302I01.png" width="800" height="418" alt="The user profile page."/&gt;
&lt;/div&gt;

&lt;p&gt;Above is a user profile page from a Rails application. There&amp;rsquo;s an &amp;ldquo;Edit Profile&amp;rdquo; link at the bottom of the page and clicking this link will take us to a page where we can edit our details.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/859/original/E302I02.png" width="800" height="543" alt="The edit user profile page."/&gt;
&lt;/div&gt;

&lt;p&gt;Instead of using a separate editing page we want to give users the ability to edit the fields directly inline on the profile page by clicking on any field. Doing this should make the field editable and hitting Enter or tabbing out of the field should save any changes made to the database.&lt;/p&gt;

&lt;h3&gt;Best In Place&lt;/h3&gt;
 
&lt;p&gt;There are a number of Rails plugins that can help us to add in-place editing to our application and there&amp;rsquo;s a comprehensive list of them at &lt;a href="https://www.ruby-toolbox.com/categories/rails_in_place_editing"&gt;The Ruby Toolbox&lt;/a&gt;. The one we&amp;rsquo;ll be using is called &lt;a href="https://github.com/bernat/best_in_place"&gt;Best In Place&lt;/a&gt;, although the others are worth taking a look at. Best In Place is a fork of another project called &lt;a href="https://github.com/janv/rest_in_place"&gt;Rest in Place&lt;/a&gt; and what makes it worth using is the &lt;code&gt;best_in_place&lt;/code&gt; helper method it offers. This makes it easy to add in-place editing fields in our Rails applications.&lt;/p&gt;

&lt;p&gt;Best In Place has a &lt;a href="https://github.com/janv/rest_in_place"&gt;demo page&lt;/a&gt; and if we try it we&amp;rsquo;ll see that we can edit any field by clicking it. Doing this replaces the static text with a form field appropriate for that type of data that&amp;rsquo;s being edited. When we hit enter for click out of the field the changes are sent back to the server and the database is updated. Best in place supports validations so if we enter, say, an invalid email address we&amp;rsquo;ll see an error message and the entered value will revert back to the last valid value.  It also supports different data types and so can show a dropdown menu for editing an association or toggle between two values for a boolean field. Let&amp;rsquo;s see what&amp;rsquo;s involved in adding it to our profile page.&lt;/p&gt;

&lt;h3&gt;Adding Best In Place to Our Application&lt;/h3&gt;

&lt;p&gt;To add Best in Place to our app we first need to add its gem to our application&amp;rsquo;s Gemfile and run &lt;code&gt;bundle&lt;/code&gt;.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/Gemfile&lt;/p&gt;
&lt;pre class="ruby"&gt;source &amp;#x27;http://rubygems.org&amp;#x27;

gem &amp;#x27;rails&amp;#x27;, &amp;#x27;3.1.3&amp;#x27;

gem &amp;#x27;sqlite3&amp;#x27;

# Gems used only for assets and not required
# in production environments by default.
group :assets do
  gem &amp;#x27;sass-rails&amp;#x27;,   &amp;#x27;~&amp;gt; 3.1.5&amp;#x27;
  gem &amp;#x27;coffee-rails&amp;#x27;, &amp;#x27;~&amp;gt; 3.1.1&amp;#x27;
  gem &amp;#x27;uglifier&amp;#x27;, &amp;#x27;&amp;gt;= 1.0.3&amp;#x27;
end

gem &amp;#x27;jquery-rails&amp;#x27;
gem &amp;#x27;best_in_place&amp;#x27;&lt;/pre&gt;

&lt;p&gt;The gem includes two JavaScript files that we&amp;rsquo;ll need to include in our application, &lt;code&gt;jquery.purr&lt;/code&gt;, a jQuery plugin, and &lt;code&gt;best_in_place&lt;/code&gt;. Since this is a Rails 3.1 app we can add them to the JavaScript manifest file.&lt;/p&gt; 

&lt;p class="codeFilePath"&gt;/app/assets/javascripts/application.js&lt;/p&gt;
&lt;pre class="javascript"&gt;//= require jquery
//= require jquery_ujs
//= require jquery.purr
//= require best_in_place
//= require_tree .&lt;/pre&gt;

&lt;p&gt;We need to define the fields that will be editable and we&amp;rsquo;ll do this in the &lt;code&gt;users&lt;/code&gt; CoffeeScript file. All we have to do is call &lt;code&gt;best_in_place()&lt;/code&gt; on any elements we want to be editable. We&amp;rsquo;ll apply it to elements with the class &lt;code&gt;best_in_place&lt;/code&gt; which is what Best In Place uses internally.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/javascripts/users.js.coffee&lt;/p&gt;
&lt;pre class="coffeescript"&gt;jQuery -&amp;gt;
  $(&amp;#x27;.best_in_place&amp;#x27;).best_in_place()&lt;/pre&gt;

&lt;p&gt;Now that we have Best In Place set up we can start to apply it to our User Profile page. Here&amp;rsquo;s how the page&amp;rsquo;s template currently looks:&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/users/show.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;h1&amp;gt;User Profile&amp;lt;/h1&amp;gt;

&amp;lt;p&amp;gt;
  &amp;lt;b&amp;gt;Name:&amp;lt;/b&amp;gt;
  &amp;lt;%= @user.name %&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
  &amp;lt;b&amp;gt;Email:&amp;lt;/b&amp;gt;
  &amp;lt;%= @user.email %&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
  &amp;lt;b&amp;gt;Gender:&amp;lt;/b&amp;gt;
  &amp;lt;%= @user.gender %&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
  &amp;lt;b&amp;gt;Public profile:&amp;lt;/b&amp;gt;
  &amp;lt;%= @user.public_profile %&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
  &amp;lt;%= @user.bio %&amp;gt;
&amp;lt;/p&amp;gt;

&amp;lt;%= link_to &amp;#x27;Edit Profile&amp;#x27;, edit_user_path(@user) %&amp;gt;&lt;/pre&gt;

&lt;p&gt;The template simply outputs the value for each field. We&amp;rsquo;ll add Best In Place&amp;rsquo;s helper method to the &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;email&lt;/code&gt; fields. This method takes two arguments, the object we&amp;rsquo;re viewing and a symbol for the field we want to edit.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/users/show.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;p&amp;gt;
  &amp;lt;b&amp;gt;Name:&amp;lt;/b&amp;gt;
  &amp;lt;%= best_in_place @user, :name %&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
  &amp;lt;b&amp;gt;Email:&amp;lt;/b&amp;gt;
  &amp;lt;%= best_in_place @user, :email %&amp;gt;
&amp;lt;/p&amp;gt;&lt;/pre&gt;

&lt;p&gt;When we load the user profile page now and click on either the &lt;code&gt;name&lt;/code&gt; or &lt;code&gt;email&lt;/code&gt; field that field becomes editable.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/860/original/E302I03.png" width="800" height="429" alt="The name field is now editable."/&gt;
&lt;/div&gt;

&lt;h3&gt;Storing Changes&lt;/h3&gt;

&lt;p&gt;When we make a change a field then click away from it the field reverts to its previous value, which isn&amp;rsquo;t what we want to happen. If we then reload the page, though, we&amp;rsquo;ll see a message telling us that the user has been updated and the page shows the changed value.&lt;/p&gt;


&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/861/original/E302I04.png" width="800" height="458" alt="The page shows as updated when we reload it."/&gt;
&lt;/div&gt;

&lt;p&gt;This is happening because Best In Place uses JSON to send updates back to the server but our &lt;code&gt;UsersController&lt;/code&gt; isn&amp;rsquo;t set to respond to JSON requests correctly. This controller uses the usual seven RESTful action, which Best In Place expects, and when we change value in the name field the &lt;code&gt;update&lt;/code&gt; action is triggered. The correct parameters are sent to the action but it doesn&amp;rsquo;t respond to JSON requests as it should.&lt;/p&gt;

&lt;p&gt;To fix this we could add a &lt;code&gt;respond_to&lt;/code&gt; block in &lt;code&gt;update&lt;/code&gt; or, as this is a Rails 3 application, use &lt;code&gt;respond_with&lt;/code&gt; which will handle everything for us. This expects a &lt;code&gt;respond_to&lt;/code&gt; call at the top of the controller so we&amp;rsquo;ll need to add that as well.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/controllers/users_controller.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;class UsersController &amp;lt; ApplicationController
  respond_to :html, :json
 
  # Other actions omitted.
 
  def update
    @user = User.find(params[:id])
    @user.update_attributes(params[:user])
    respond_with @user
  end

end&lt;/pre&gt;

&lt;p&gt;If we need to customize this behaviour further we can use a full &lt;code&gt;respond_to&lt;/code&gt; block in the update action and there&amp;rsquo;s an example of how to do this in Best in Place&amp;rsquo;s &lt;a href="https://github.com/bernat/best_in_place/blob/master/README.md"&gt;README&lt;/a&gt;.&lt;/p&gt; 

&lt;p&gt;Now that our controller responds to JSON the in-place functionality works correctly. Any changes we make are added to the database and the UI updates as we expect.&lt;/p&gt; 

&lt;p&gt;Validations also work, too. If we enter an invalid email address an error message will show, although by default it isn&amp;rsquo;t particularly visible.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/862/original/E302I05.png" width="800" height="475" alt="Validation errors aren't pretty by default."/&gt;
&lt;/div&gt;

&lt;p&gt;We can pretty this error message up with some CSS.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/stylesheets/users.css.scss&lt;/p&gt;
&lt;pre class="css"&gt;.purr {
  position: fixed;
  top: 30px;
  right: 100px;
  width: 250px;
  padding: 20px;
  background-color: #FCC;
  border: solid 2px #666;
  &amp;amp;:first-letter { text-transform: uppercase };
}&lt;/pre&gt;

&lt;p&gt;All of the styles are in a &lt;code&gt;purr&lt;/code&gt; class which is what Best in Place uses. When we reload the page now and enter a bad email address again we get a prettier error message.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/863/original/E302I06.png" width="800" height="475" alt="Validation error messages look better after adding some CSS."/&gt;
&lt;/div&gt; 

&lt;h3&gt;Handling Other Types of Data&lt;/h3&gt;

&lt;p&gt;We&amp;rsquo;ve only made the &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;email&lt;/code&gt; fields editable so far, now we&amp;rsquo;ll look at the other attributes on the user page. The &lt;code&gt;bio&lt;/code&gt; field contains a long piece of text but by default &lt;code&gt;best_in_place&lt;/code&gt; will only show a single line text box. We can change this behaviour by specifying the &lt;code&gt;type&lt;/code&gt; attribute.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/users/show.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;%= best_in_place @user, :bio, type: :textarea %&amp;gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;public_profile&lt;/code&gt; field is boolean so we should use the &lt;code&gt;checkbox&lt;/code&gt; type and pass in the values that should be displayed in a &lt;code&gt;:collection&lt;/code&gt; option.&lt;/p&gt; 

&lt;p class="codeFilePath"&gt;/app/views/users/show.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;%= best_in_place @user, :public_profile, type: :checkbox, collection: %w[No Yes] %&amp;gt;&lt;/pre&gt;


&lt;p&gt;Clicking on the current public profile option now will toggle between these two options. The gender option can be treated in a similar way, but here we use &lt;code&gt;:select&lt;/code&gt; instead of &lt;code&gt;:checkbox&lt;/code&gt; and pass in a two-dimensional array of options.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/users/show.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;%= best_in_place @user, :gender, type: :select, :collection [[&amp;quot;Male&amp;quot;, &amp;quot;Male&amp;quot;], [&amp;quot;Female&amp;quot;, &amp;quot;Female&amp;quot;], [&amp;quot;&amp;quot;, &amp;quot;Unspecified&amp;quot;]] %&amp;gt;&lt;/pre&gt;
&lt;p&gt;This option will show a dropdown menu when we click the current gender.&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s is for this episode. We now have a fully-featured in-place editing option for each field in our User Profile page. There may be times when we want to do something a little more complicated, for instance displaying options for an association or maybe a formatted price field where the value displayed may be different from the one in the edit field. Unfortunately this is a little difficult to do with the current version of Best In Place. For these situations it&amp;rsquo;s still best to fall back to a &amp;lsquo;traditional&amp;rsquo; edit form or write your own solution from scratch.&lt;/p&gt;
</description>
      <pubDate>Sun, 29 Jan 2012 17:53:45 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/302-in-place-editing</guid>
      <link>http://asciicasts.com/episodes/302-in-place-editing</link>
    </item>
    <item>
      <title>Contributing to Open Source</title>
      <description>&lt;p&gt;&lt;a href="https://github.com/"&gt;Github&lt;/a&gt; makes it incredibly easy to contribute to open source projects. In this episode we&amp;rsquo;ll show you how to do so by submitting a pull request to &lt;a href="https://github.com/myronmarston/vcr"&gt;the VCR  project&lt;/a&gt;. We covered this gem, which provides a way to record HTTP interactions and play them back in order to speed up tests, back in &lt;a href="http://railscasts.com/episodes/291-testing-with-vcr"&gt;episode 291&lt;/a&gt;. Myron Marston, the gem&amp;rsquo;s author, is very good at keeping up with contributions from other people.&lt;/p&gt;

&lt;p&gt;Let&amp;rsquo;s say that we&amp;rsquo;ve found an issue with this gem that we&amp;rsquo;d like to contribute a patch for.  The first thing we should do is look at the gem&amp;rsquo;s issue tracker and make sure that it hasn&amp;rsquo;t already been addressed. If the project has a mailing list then it&amp;rsquo;s also a good idea to search this for any items related to the issue we&amp;rsquo;ve found. For large changes it&amp;rsquo;s a good idea to discuss it first to see if the change is needed.&lt;/p&gt;

&lt;h3&gt;&lt;a href="http://www.youtube.com/watch?feature=player_detailpage&amp;amp;v=nHLzj_6HCjU#t=270s"&gt;Fork It!&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;Once we&amp;rsquo;re ready to start on our fix the first step is to fork the project. To do this we need to visit the project&amp;rsquo;s home page and click the &amp;lsquo;fork&amp;rsquo; button. This will give us our own copy of the repository and will take a few seconds to complete but once it has we can visit our new fork and get its URL so that we can clone it.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ git clone git@github.com:eifion/vcr.git
$ cd vcr&lt;/pre&gt;

&lt;p&gt;When we&amp;rsquo;ve cloned the repository we should see what branches it has.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ git branch -r
  origin/1-x-stable
  origin/HEAD -&amp;gt; origin/master
  origin/jruby_nailgun
  origin/master&lt;/pre&gt;

&lt;p&gt;One thing to notice here is that there&amp;rsquo;s a branch for the stable release of version 1 which is the current version of the gem.  The master branch points to version 2 which is currently in pre-release. This is something to keep in mind: the version of the gem that you&amp;rsquo;re using may different from the one you&amp;rsquo;re working on in the code.&lt;/p&gt;

&lt;p&gt;When setting up the development environment for a project it&amp;rsquo;s a good idea to check the documentation. In this case there&amp;rsquo;s a development section in the &lt;a href="https://github.com/eifion/vcr/blob/master/README.md"&gt;README file&lt;/a&gt; that tells us that pull requests are welcome, but that any changes we made need to be fully covered by tests. The README doesn&amp;rsquo;t have any instructions on running the gem&amp;rsquo;s test suite but it&amp;rsquo;s encouraging to see that Travis CI says that the tests are all &lt;a href="http://travis-ci.org/#!/myronmarston/vcr"&gt;currently passing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The project has a Gemfile so it uses Bundler to manage its dependencies. We should be able to install these by running &lt;code&gt;bundle install&lt;/code&gt; but when we try this we see an error. This is to be expected as every system is set up differently so we should expect to run into a couple of hiccups when we try to set up a project in our environment.&lt;/p&gt;

&lt;p&gt;The error we see is related to the &lt;code&gt;rb-fsevent&lt;/code&gt; gem and a quick search tells us that this problem is related to our set up. We&amp;rsquo;re using the &lt;a href="https://github.com/kennethreitz/osx-gcc-installer"&gt;GCC Installer&lt;/a&gt; rather than the full Xcode install on OS X and the current version of  won&amp;rsquo;t install this way. This problem has now been fixed in &lt;a href="https://github.com/kennethreitz/osx-gcc-installer"&gt;&lt;code&gt;rb-fsevent&lt;/code&gt;&lt;/a&gt; but the fix isn&amp;rsquo;t yet in a stable release. We can solve this problem by setting the version of &lt;code&gt;rb-fsevent&lt;/code&gt; in the Gemfile to the current pre-release version.&lt;/p&gt;

```*/Gemfile
# Additional gems that are useful, but not required for development.
group :extras do
  gem 'guard-rspec'
  gem 'growl'
  gem 'relish', '~&gt; 0.5.0'
  gem 'fuubar'
  gem 'fuubar-cucumber'

  platforms :mri do
    gem 'rcov'
    gem 'rb-fsevent', '0.9.0.pre4'
  end

  platforms :mri_18, :jruby do
    gem 'ruby-debug'
  end

  platforms :mri_19 do
    gem 'ruby-debug19'
  end unless RUBY_VERSION == '1.9.3'
end
```

&lt;p&gt;When we run bundle now everything installs correctly.&lt;/p&gt;

&lt;h3&gt;Running The Tests&lt;/h3&gt;

&lt;p&gt;Next we&amp;rsquo;ll try to run the gem&amp;rsquo;s tests. This is often set as the default Rake task so we should be able to run them by running &lt;code&gt;rake&lt;/code&gt;. It&amp;rsquo;s better, though, to run &lt;code&gt;bundle exec rake&lt;/code&gt; though so we know that it&amp;rsquo;s using Bundler.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ bundle exec rake
  1504/1504:   100% |==========================================| ETA:  00:00:00&lt;/pre&gt; 
  
&lt;p&gt;The tests pass with a few pending issues which is fine. After the tests have run the Cucumber scenarios are executed. We get one failure here with a long error message, the nub of which says &amp;ldquo;&lt;code&gt;no such file to load -- spec&lt;/code&gt;&amp;rdquo;. It looks like we&amp;rsquo;re missing a dependency that Bundler hasn&amp;rsquo;t set up.&lt;/p&gt; 

&lt;p&gt;After some investigation it turns out that this project uses &lt;a href="http://book.git-scm.com/5_submodules.html"&gt;Git submodules&lt;/a&gt; so to get it working we need to run these two commands.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ git submodule init
$ git submodule update&lt;/pre&gt;

&lt;p&gt;These will copy over the submodule repository for us. We can try running the tests again now and see if they pass and this time they do.&lt;/p&gt;

&lt;h3&gt;Making The Changes&lt;/h3&gt;

&lt;p&gt;We ran into a couple of problems getting the tests to pass but we&amp;rsquo;ve finally made it. This is to be expected as everyone&amp;rsquo;s development environment is different. We could have saved some time if the documentation has been better on getting the project set up. So, our first pull request will be to add some better documentation to the README file for setting up the development environment.&lt;/p&gt; 

&lt;p&gt;It turns out that there&amp;rsquo;s already a wiki page dedicated to contributing to the VCR project, but it only contains the basics on getting set up. We&amp;rsquo;ll edit this page to add some more information based on the problems we&amp;rsquo;ve had. Once we&amp;rsquo;ve made our changes we can submit a pull request which adds a link to the README for this contributing guide.&lt;/p&gt;

&lt;p&gt;Before we make any changes to the code we&amp;rsquo;ll make sure we have a clean working directory.&lt;/p&gt; 

&lt;pre class="terminal"&gt;$ git status
# On branch master
# Changes not staged for commit:
#   (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to update what will be committed)
#   (use &amp;quot;git checkout -- &amp;lt;file&amp;gt;...&amp;quot; to discard changes in working directory)
#
#	modified:   Gemfile
#
no changes added to commit (use &amp;quot;git add&amp;quot; and/or &amp;quot;git commit -a&amp;quot;)&lt;/pre&gt;

&lt;p&gt;As we&amp;rsquo;ve modified the Gemfile we&amp;rsquo;ll revert this change before we go any further.&lt;/p&gt;

&lt;pre class="terminal"&gt;
$ git checkout .
noonoo:vcr eifion$ git status
# On branch master
nothing to commit (working directory clean)&lt;/pre&gt;

&lt;p&gt;It&amp;rsquo;s a good idea to setup a separate Git branch for each pull request we want to make so we&amp;rsquo;ll do that now.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ git checkout -b readme-contributing-link&lt;/pre&gt;

&lt;p&gt;Now we can make our change. In the development section of &lt;code&gt;README.md&lt;/code&gt; we&amp;rsquo;ll add a link to the wiki page we just changed.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/README.md&lt;/p&gt;
&lt;pre class="terminal"&gt;## Development

* Source hosted on [GitHub](http://github.com/myronmarston/vcr).
* Direct questions and discussions to the [mailing list](http://groups.google.com/group/vcr-ruby).
* Report issues on [GitHub Issues](http://github.com/myronmarston/vcr/issues).
* Pull requests are very welcome! Please include spec and/or feature coverage for every patch,
  and create a topic branch for every separate change you make.
* See the [Contributing](https://github.com/myronmarston/vcr/blob/master/CONTRIBUTING.md)
  guide for instructions on running the specs and features.&lt;/pre&gt;
  
&lt;p&gt;Once we&amp;rsquo;ve made our changes we can run git diff to see the changes we&amp;rsquo;ve made. If we&amp;rsquo;re happy with them we can commit them by running&lt;/p&gt;

&lt;pre class="terminal"&gt;$ git commit -a -m &amp;quot;adding contributing link to readme.&amp;quot;Next we need to push our branch to our remote repository.
$ git push origin readme-contributing-link
Counting objects: 5, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 328 bytes, done.
Total 3 (delta 2), reused 0 (delta 0)
To git@github.com:eifion/vcr.git
 * [new branch]      readme-contributing-link -&amp;gt; readme-contributing-link&lt;/pre&gt;
 
&lt;p&gt;This will add the branch to our Github repository.&lt;/p&gt;

&lt;p&gt;When we visit our forked repository on Github now we can change the current branch to the one we just added.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/851/original/E300I01.png" width="944" height="563" alt="Selecting the correct branch on Github."/&gt;
&lt;/div&gt;

&lt;p&gt;We can then click &amp;ldquo;Pull Request&amp;rdquo; to submit our pull request to the original owner. We&amp;rsquo;ll need to fill in a form explaining the changes we&amp;rsquo;ve made and then we can send off our request.&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s all we need to do to submit a pull request to an open source project on Github. If it&amp;rsquo;s accepted our change will make it easier for the next person who want to contribute. Now it&amp;rsquo;s your turn.&lt;/p&gt;
</description>
      <pubDate>Sun, 29 Jan 2012 17:41:57 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/300-contributing-to-open-source</guid>
      <link>http://asciicasts.com/episodes/300-contributing-to-open-source</link>
    </item>
    <item>
      <title>Getting Started With Spree</title>
      <description>&lt;p&gt;&lt;a href="http://spreecommerce.com/"&gt;Spree&lt;/a&gt; is a fully-featured e-commerce solution that can be easily integrated into a Rails application. If you need to turn a Rails app into a store that sells products then Spree is one of the quickest ways to do this. In this episode we&amp;rsquo;ll set up Spree in a new Rails application and customize some of its functionality so that you can get an idea as to how it works and see if it fits the needs of your application.&lt;/p&gt;

&lt;h3&gt;Installing Spree&lt;/h3&gt;

&lt;p&gt;Spree depends on &lt;a href="http://www.imagemagick.org/script/index.php"&gt;ImageMagick&lt;/a&gt; to handle the image processing it does so we&amp;rsquo;ll need to install it before we can install Spree. The easiest way to do this is to use HomeBrew.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ brew install imagemagick&lt;/pre&gt;

&lt;p&gt;Once ImageMagick has installed we&amp;rsquo;ll create a new Rails 3.1 application that we&amp;rsquo;ll call &lt;code&gt;store&lt;/code&gt;. Spree can be integrated into an existing Rails application but it&amp;rsquo;s a good idea to try it out in a new app first so that you can see what it adds.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ rails new store&lt;/pre&gt;

&lt;p&gt;To install Spree and its many dependencies we need to add it to the application&amp;rsquo;s &lt;code&gt;Gemfile&lt;/code&gt; and then run &lt;code&gt;bundle&lt;/code&gt;. Spree is updated pretty regularly so we&amp;rsquo;ve specified the version number. Version &lt;code&gt;0.70.1&lt;/code&gt; is the current version at the time of writing.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/Gemfile&lt;/p&gt;
&lt;pre class="ruby"&gt;source &amp;#x27;http://rubygems.org&amp;#x27;

gem &amp;#x27;rails&amp;#x27;, &amp;#x27;3.1.1&amp;#x27;

gem &amp;#x27;sqlite3&amp;#x27;

# Gems used only for assets and not required
# in production environments by default.
group :assets do
  gem &amp;#x27;sass-rails&amp;#x27;,   &amp;#x27;~&amp;gt; 3.1.4&amp;#x27;
  gem &amp;#x27;coffee-rails&amp;#x27;, &amp;#x27;~&amp;gt; 3.1.1&amp;#x27;
  gem &amp;#x27;uglifier&amp;#x27;, &amp;#x27;&amp;gt;= 1.0.3&amp;#x27;
end

gem &amp;#x27;jquery-rails&amp;#x27;

group :test do
  # Pretty printed test output
  gem &amp;#x27;turn&amp;#x27;, :require =&amp;gt; false
end

gem &amp;#x27;spree&amp;#x27;, &amp;#x27;0.70.1&amp;#x27;&lt;/pre&gt;

&lt;p&gt;Once the gems have installed we need to run a generator to add Spree to our site.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ rails g spree:site&lt;/pre&gt;

&lt;p&gt;This command does a number of things. It copies over the migration files that create the database tables that Spree needs and it customizes several of our application&amp;rsquo;s files, mostly ones under &lt;code&gt;app/assets&lt;/code&gt;. The generator will also remove the &lt;code&gt;application.js&lt;/code&gt; and &lt;code&gt;application.css&lt;/code&gt; files, so if you&amp;rsquo;ve customized these you&amp;rsquo;ll need to integrate your changes with the way that Spree organizes the application&amp;rsquo;s assets.&lt;/p&gt;

&lt;p&gt;If we look at the application&amp;rsquo;s &lt;code&gt;/app/assets&lt;/code&gt; directory now we&amp;rsquo;ll see that each directory in there, &lt;code&gt;images&lt;/code&gt;, &lt;code&gt;javascripts&lt;/code&gt; and &lt;code&gt;stylesheets&lt;/code&gt;, now has &lt;code&gt;admin&lt;/code&gt; and &lt;code&gt;store&lt;/code&gt; subdirectories. This is done so that we can keep the assets for the public-facing store and the private admin pages separate. If we look at the store&amp;rsquo;s &lt;code&gt;all.css&lt;/code&gt; file (or &lt;code&gt;application.js&lt;/code&gt; file) we&amp;rsquo;ll see that it &lt;code&gt;require&lt;/code&gt;s several files that are inside Spree and automatically loads them.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/stylesheests/store/all.css&lt;/p&gt;
&lt;pre class="css"&gt;/*
 * This is a manifest file that&amp;#x27;ll automatically include all the stylesheets available in this directory
 * and any sub-directories. You&amp;#x27;re free to add application-wide styles to this file and they&amp;#x27;ll appear at
 * the top of the compiled file, but it&amp;#x27;s generally better to create a new file per style scope.
 *

 *= require store/spree_core
 *= require store/spree_auth
 *= require store/spree_api
 *= require store/spree_promo
 *= require store/spree_dash

 *= require_self
 *= require_tree .
*/&lt;/pre&gt;

&lt;p&gt;There&amp;rsquo;s one more command we need to run to finish setting everything up. This will run the migrations that were copied over earlier. Note that it will ask if we want to destroy any existing data in the database.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ rake db:bootstrap
This task will destroy any data in the database. Are you sure you want to 
continue? [y/n] y
db/development.sqlite3 already exists
...&lt;/pre&gt;

&lt;p&gt;This command also asks us for an email address and a password for the admin user; we&amp;rsquo;ll use the defaults that are provided. Finally we&amp;rsquo;ll be asked it we want to load some sample data and we&amp;rsquo;ll do this so that we have something to see in the store.&lt;/p&gt;

&lt;pre class="terminal"&gt;Email [spree@example.com]: 
Password [spree123]: 
Load Sample Data? [y/n]: y&lt;/pre&gt;

&lt;p&gt;Now we can start up our application&amp;rsquo;s server and take a look.&lt;/p&gt;

&lt;h3&gt;A First Look At Spree&lt;/h3&gt;

&lt;p&gt;This is what our store looks like. By default there&amp;rsquo;s no theme applied so it looks fairly plain, but we do have a full e-commerce store on our site containing the sample products that we loaded when we ran the generator, including a shopping cart and a checkout process.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/841/original/E298I01.png" width="842" height="368" alt="The basic Spree site."/&gt;
&lt;/div&gt;

&lt;p&gt;There&amp;rsquo;s also an administration section available at &lt;a href="http://localhost:3000/admin"&gt;&lt;code&gt;http://localhost:3000/admin&lt;/code&gt;&lt;/a&gt; and once we&amp;rsquo;ve logged in using the email address and password we supplied when we ran the generator we can view it. This is also pretty fully featured and allows us to see orders that were placed and various charts to see what the best selling products are. There are also pages that let us view and edit the products and orders.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/842/original/E298I02.png" width="842" height="464" alt="The admin site."/&gt;
&lt;/div&gt;

&lt;p&gt;The administration section also has a number of configuration options including the ability to change the payment methods your store supports. There are different payment methods for the different environments and when we edit one of these we can change the payment gateway that it uses. When we do so Spree will give us the option to enter credentials for that gateway so that we can configure it for any payment gateways we have.&lt;/p&gt;

&lt;h3&gt;Customizing Spree&lt;/h3&gt;

&lt;p&gt;We have a fairly comprehensive e-commerce solution in our Rails application now but what if we want more control over exactly how the store looks to the customer? The default look is fairly bland and this is because no theme is applied. We&amp;rsquo;ll spend the rest of this episode showing various ways that we can customize the look and behaviour of the store.&lt;/p&gt; 

&lt;p&gt;Spree supports themes and extensions and the &lt;a href="https://github.com/spree/spree_blue_theme"&gt;Blue Theme&lt;/a&gt; serves as a good example of how we can customize Spree. This theme, like most things in Spree, is a Rails engine, and we can use it to override various things in the &lt;code&gt;app/assets&lt;/code&gt; and &lt;code&gt;app/overrides&lt;/code&gt; directories. To install the theme we add the following line to the &lt;code&gt;Gemfile&lt;/code&gt; and run &lt;code&gt;bundle&lt;/code&gt;.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/Gemfile&lt;/p&gt;
&lt;pre class="ruby"&gt;gem &amp;#x27;spree_blue_theme&amp;#x27;, :git =&amp;gt; &amp;#x27;git://github.com/spree/spree_blue_theme.git&amp;#x27;&lt;/pre&gt;

&lt;p&gt;To get the theme to work we found it necessary to change a stylesheet file and replace the default styles (the ones that begin with &lt;code&gt;require store/&lt;/code&gt;) with the one provided by the theme.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/stylesheets/store/all.css&lt;/p&gt;
&lt;pre class="css"&gt;/*
 * This is a manifest file that&amp;#x27;ll automatically include all the stylesheets available in this directory
 * and any sub-directories. You&amp;#x27;re free to add application-wide styles to this file and they&amp;#x27;ll appear at
 * the top of the compiled file, but it&amp;#x27;s generally better to create a new file per style scope.
 *

 *= require store/screen
 *= require_self
 *= require_tree .
*/&lt;/pre&gt;


&lt;p&gt;The store now looks quite different and whether we choose to use themes or not it serves as a good example of we can customize the look of a Spree application.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/843/original/E298I03.png" width="842" height="562" alt="The site with the theme applied."/&gt;
&lt;/div&gt;

&lt;h3&gt;Customizing Individual Parts of The Site&lt;/h3&gt;

&lt;p&gt;Next we&amp;rsquo;ll look at customizing parts of the site individually. If, for example, we want to change the logo at the top left of the page with one of our own we can do so. The default image is stored at &lt;code&gt;/assets/admin/bg/spree_50.png&lt;/code&gt; and is provided by the Spree engine but we can override this in our application.&lt;/p&gt;

&lt;p&gt;There are two ways we can do this. One way is to create a &lt;code&gt;/app/assets/images/admin/bg&lt;/code&gt; directory in our application and copy another image, say the default &lt;code&gt;rails.png&lt;/code&gt; image, there, renaming it to &lt;code&gt;spree_50.png&lt;/code&gt;. This image will override the default one and we&amp;rsquo;ll see it when we reload the page (although we may have to restart the server for the change to be picked up).&lt;/p&gt; 

&lt;p&gt;Another way we can change the logo is to override part of Spree&amp;rsquo;s configuration. The default configuration is set in a &lt;a href="https://github.com/spree/spree/blob/master/core/app/models/spree/app_configuration.rb"&gt;file&lt;/a&gt; that has a large number of configuration options. These includie a logo option that points to the location of the default logo file. Spree provides an entire preferences system that allows us to configure these options in various ways. We can do it through the database, through an admin panel or we can create an initializer and make the changes through Ruby. We&amp;rsquo;ll take the latter option and create a new &lt;code&gt;spree.rb&lt;/code&gt; configuration file.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/config/initializers/spree.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;Spree::Config.set(logo: &amp;quot;store/rails.png&amp;quot;)&lt;/pre&gt;

&lt;p&gt;We call &lt;code&gt;Spree::Config.set&lt;/code&gt; to set configuration options and having set the logo option we can move our image to &lt;code&gt;/app/assets/images/store/&lt;/code&gt; and rename it to &lt;code&gt;rails.png&lt;/code&gt;. When we reload the page now the image is at &lt;code&gt;http://localhost:3000/assets/store/rails.png&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We can also customize Spree by overriding parts of a a template. To do this we first have to find the template in the Spree source code. This isn&amp;rsquo;t difficult to do but we&amp;rsquo;ll need to be aware that we browse the source code of the same version of Spree that we&amp;rsquo;ve included. In our case we&amp;rsquo;ll need to browse &lt;a href="https://github.com/spree/spree/tree/v0.70.1"&gt;version 0.70.1&lt;/a&gt;. Once we&amp;rsquo;re sure we&amp;rsquo;re looking at the right version can navigate to &lt;code&gt;core/app/views/layouts&lt;/code&gt; where we&amp;rsquo;ll find a &lt;code&gt;spree_application.html.erb&lt;/code&gt; file. This is the template that we want to override as it contains the code that renders the logo.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/layouts/spree_application.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;div id=&amp;quot;logo&amp;quot; data-hook&amp;gt;
  &amp;lt;%= logo %&amp;gt;
&amp;lt;/div&amp;gt;&lt;/pre&gt;

&lt;p&gt;There are a couple of ways that we can override this to change the way it looks. We could copy the entire layout file into the same location in our application. Spree will then use this template over its default one and any changes we make to it will be reflected in our application.&lt;/p&gt;

&lt;p&gt;Another way is to use a gem called &lt;a href="https://github.com/railsdog/deface"&gt;Deface&lt;/a&gt;. We don&amp;rsquo;t have to install this gem as it&amp;rsquo;s already a dependency of Spree and we can use it in the &lt;code&gt;/app/overrides&lt;/code&gt; directory that Spree generated to override parts of Spree&amp;rsquo;s templates. The README information on the project&amp;rsquo;s homepage contains various examples showing how it works. We&amp;rsquo;ll copy the first example listed into a new file in this directory called &lt;code&gt;logo.rb&lt;/code&gt; and modify it for the part of the page we want to change.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/overrides/logo.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;Deface::Override.new(:virtual_path =&amp;gt; &amp;quot;layouts/spree_application&amp;quot;, 
                     :name =&amp;gt; &amp;quot;logo&amp;quot;, 
                     :replace_contents =&amp;gt; &amp;quot;#logo&amp;quot;, 
                     :text =&amp;gt; &amp;quot;Store&amp;quot;)&lt;/pre&gt;                   

&lt;p&gt;There are four options we need to specify here. The &lt;code&gt;virtual_path&lt;/code&gt; is the path to the erb template we want to modify, while the &lt;code&gt;name&lt;/code&gt; can be anything we want. We want to replace the contents of a &lt;code&gt;div&lt;/code&gt; with an &lt;code&gt;id&lt;/code&gt; of &lt;code&gt;logo&lt;/code&gt; so we&amp;rsquo;ll use the  &lt;code&gt;replace_contents&lt;/code&gt; option and pass it a CSS selector that matches that &lt;code&gt;div&lt;/code&gt;. The final option specifies what we want to replace the contents with; for now we&amp;rsquo;ll replace the logo with the text &amp;ldquo;Store&amp;rdquo;.&lt;/p&gt;

&lt;p&gt;When we reload the page now the logo has gone and the text appears in its place.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/844/original/E298I04.png" width="842" height="370" alt="The logo has now been replaced by the word &amp;ldquo;Store&amp;rdquo;."/&gt;
&lt;/div&gt;

&lt;p&gt;We&amp;rsquo;ve replaced the image with the text but we need to style it a little. We can add the styling under the &lt;code&gt;stylesheets/store&lt;/code&gt; directory and it&amp;rsquo;s good practice to do this in a new file. We&amp;rsquo;ll make the text larger and colour it white.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/stylesheets/store/layout.css.scss&lt;/p&gt;
&lt;pre class="css"&gt;#logo {
  font-size: 32px;
  color: #FFF;
}&lt;/pre&gt;

&lt;p&gt;When we visit the application now we&amp;rsquo;ll see the customized styling.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/845/original/E298I05.png" width="842" height="370" alt="The text is now styled."/&gt;
&lt;/div&gt;

&lt;p&gt;That&amp;rsquo;s it for this episode. There&amp;rsquo;s a lot more to Spree than we&amp;rsquo;ve covered here and you&amp;rsquo;re encouraged to read the &lt;a href="http://guides.spreecommerce.com/"&gt;Spree Guides&lt;/a&gt; for more information. There&amp;rsquo;s a topic there for pretty much everything you could need to know about Spree.&lt;/p&gt;
</description>
      <pubDate>Sun, 29 Jan 2012 17:27:56 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/298-getting-started-with-spree</guid>
      <link>http://asciicasts.com/episodes/298-getting-started-with-spree</link>
    </item>
    <item>
      <title>Mercury Editor</title>
      <description>
&lt;p&gt;&lt;a href="http://jejacks0n.github.com/mercury/"&gt;Mercury&lt;/a&gt; is a project by Jeremy Jackson that allows you to edit sections of an HTML page directly in the browser. You can see it in action by clicking &amp;ldquo;Test it Out&amp;rdquo; on the project&amp;rsquo;s home page. Doing so adds a toolbar to the top of the page and highlights certain sections of it. You can then edit these sections directly and save the changes back to the server. In this episode we&amp;rsquo;ll add Mercury to a Rails application.&lt;/p&gt;

&lt;p&gt;Below is a page from a simple Content Management System. This application has a &lt;code&gt;Page&lt;/code&gt; model and three page records each with a name and some content. Currently there&amp;rsquo;s no way to edit the pages so we&amp;rsquo;ll add Mercury to the app so that we can edit them directly.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/823/original/E296I01.png" width="800" height="437" alt="Our Simple CMS Application."/&gt;
&lt;/div&gt;

&lt;h3&gt;Installing Mercury&lt;/h3&gt;

&lt;p&gt;The first step to installing Mercury is to go into the &lt;code&gt;/Gemfile&lt;/code&gt; and add the &lt;code&gt;mercury-rails&lt;/code&gt; gem. This gem is being developed fairly rapidly so we&amp;rsquo;ll grab a recent version directly from Github.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/Gemfile&lt;/p&gt;
&lt;pre class="ruby"&gt;source &amp;#x27;http://rubygems.org&amp;#x27;

gem &amp;#x27;rails&amp;#x27;, &amp;#x27;3.1.1&amp;#x27;
gem &amp;#x27;sqlite3&amp;#x27;

# Gems used only for assets and not required
# in production environments by default.
group :assets do
  gem &amp;#x27;sass-rails&amp;#x27;,   &amp;#x27;~&amp;gt; 3.1.4&amp;#x27;
  gem &amp;#x27;coffee-rails&amp;#x27;, &amp;#x27;~&amp;gt; 3.1.1&amp;#x27;
  gem &amp;#x27;uglifier&amp;#x27;, &amp;#x27;&amp;gt;= 1.0.3&amp;#x27;
end

gem &amp;#x27;jquery-rails&amp;#x27;
gem &amp;#x27;mercury-rails&amp;#x27;, git: &amp;#x27;https://github.com/jejacks0n/mercury.git&amp;#x27;, ref: &amp;#x27;a2b16bcdc9&amp;#x27;&lt;/pre&gt;

&lt;p&gt;The commit SHA of the version we&amp;rsquo;re using is included above so that you know which version we&amp;rsquo;ve used. As ever once we&amp;rsquo;ve changed the &lt;code&gt;Gemfile&lt;/code&gt; we&amp;rsquo;ll need to run bundle to install the new gem.&lt;/p&gt;

&lt;p&gt;Once the gem has installed we need to run Mercury&amp;rsquo;s installation generator. This will ask us if we want to install the layout and CSS overrides files and we do.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ rails g mercury:install
      create  app/assets/javascripts/mercury.js
       route  Mercury::Engine.routes
Install the layout and CSS overrides files? [yN] y
      create  app/views/layouts/mercury.html.erb
      create  app/assets/stylesheets/mercury_overrides.css&lt;/pre&gt;     
      
&lt;p&gt;The output from this command tells us that we need to run another command to install Mercury&amp;rsquo;s migrations so we&amp;rsquo;ll run that next and then migrate the database.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ rake mercury_engine:install:migrations
Copied migration 20111108202946_create_images.rb from mercury_engine
noonoo:cms eifion$ rake db:migrate
==  CreateImages: migrating ===================================================
-- create_table(:images)
   -&amp;gt; 0.0017s
==  CreateImages: migrated (0.0018s) ==========================================&lt;/pre&gt;

&lt;p&gt;Our application now has a &lt;code&gt;mercury.js&lt;/code&gt; file in its app/assets directory. This file contains all of the configuration options for Mercury and comments explaining them. We&amp;rsquo;ll come back to this file later; first we&amp;rsquo;ll address how this file is loaded. In a Rails 3.1 application this file will be loaded by default on every page as the &lt;code&gt;application.js&lt;/code&gt; manifest file includes every file under &lt;code&gt;app/assets/javascripts&lt;/code&gt;. Mercury is quite JavaScript-heavy so we only want it to load on the Mercury-editable pages. We&amp;rsquo;ll modify the manifest so that is only loads the files we specify. (As an alternative we could move the &lt;code&gt;mercury.js&lt;/code&gt; file out to &lt;code&gt;/vendor/assets&lt;/code&gt; instead.) When we&amp;rsquo;re editing a page Mercury will use its own layout file that includes this JavaScript file so though it appears that we&amp;rsquo;ve removed this file completely it will still be loaded when necessary.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/javascripts/application.js&lt;/p&gt;
&lt;pre class="javascript"&gt;// This is a manifest file that&amp;#x27;ll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they&amp;#x27;ll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It&amp;#x27;s not advisable to add code directly here, but if you do, it&amp;#x27;ll appear at the bottom of the
// the compiled file.
//
//= require jquery
//= require jquery_ujs
//= require pages&lt;/pre&gt;

&lt;p&gt;We can do something similar for Mercury&amp;rsquo;s stylesheet but we won&amp;rsquo;t do that here.&lt;/p&gt;

&lt;h3&gt;Making Pages Editable&lt;/h3&gt;

&lt;p&gt;With Mercury installed we now have access to the Mercury editor from any page in our application. To put any page into edit mode we just need to add &lt;code&gt;/editor&lt;/code&gt; between the URL&amp;rsquo;s host and path. &lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/824/original/E296I02.png" width="800" height="551" alt="The Mercury toolbar."/&gt;
&lt;/div&gt;

&lt;p&gt;Now that we know the URL to edit a page we can add the &amp;ldquo;Edit Page&amp;rdquo; link.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/pages/show.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;div id=&amp;quot;header&amp;quot;&amp;gt;
  &amp;lt;h1&amp;gt;&amp;lt;%= raw @page.name %&amp;gt;&amp;lt;/h1&amp;gt;
  &amp;lt;ul id=&amp;quot;navigation&amp;quot;&amp;gt;
  &amp;lt;% Page.all.each do |page| %&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;%= link_to_unless_current page.name, page %&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;% end %&amp;gt;
  &amp;lt;/ul&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div class=&amp;quot;content&amp;quot;&amp;gt;
  &amp;lt;%= raw @page.content %&amp;gt;

  &amp;lt;p&amp;gt;&amp;lt;%= link_to &amp;quot;Edit Page&amp;quot;, &amp;quot;/editor&amp;quot; + request.path %&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;&lt;/pre&gt;


&lt;h3&gt;Adding Editable Areas&lt;/h3&gt;

&lt;p&gt;We now have a link to edit any page but we haven&amp;rsquo;t yet defined any editable areas on the page. There are two sections we want to be editable: the page&amp;rsquo;s title and its content and each of these map to attributes in the &lt;code&gt;Page&lt;/code&gt; model. To make part of a page editable we need to wrap it in an element that has a &lt;code&gt;class&lt;/code&gt; of &lt;code&gt;mercury-region&lt;/code&gt; and a &lt;code&gt;data-type&lt;/code&gt; of &lt;code&gt;editable&lt;/code&gt;. We also need to give each wrapper element an &lt;code&gt;id&lt;/code&gt; so that we can identify it when the updated page is sent back to the server. We&amp;rsquo;ll call our two regions &lt;code&gt;page_name&lt;/code&gt; and &lt;code&gt;page_content&lt;/code&gt;.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/pages/show.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;div id=&amp;quot;header&amp;quot;&amp;gt;
  &amp;lt;h1&amp;gt;&amp;lt;span id=&amp;quot;page_name&amp;quot; class=&amp;quot;mercury-region&amp;quot; data-type=&amp;quot;editable&amp;quot;&amp;gt;&amp;lt;%= raw @page.name %&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/h1&amp;gt;
  &amp;lt;ul id=&amp;quot;navigation&amp;quot;&amp;gt;
  &amp;lt;% Page.all.each do |page| %&amp;gt;
    &amp;lt;li&amp;gt;&amp;lt;%= link_to_unless_current page.name, page %&amp;gt;&amp;lt;/li&amp;gt;
  &amp;lt;% end %&amp;gt;
  &amp;lt;/ul&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;div class=&amp;quot;content&amp;quot;&amp;gt;
  &amp;lt;div id=&amp;quot;page_content&amp;quot; class=&amp;quot;mercury-region&amp;quot; data-type=&amp;quot;editable&amp;quot;&amp;gt;
    &amp;lt;%= raw @page.content %&amp;gt;
  &amp;lt;/div&amp;gt;

  &amp;lt;p&amp;gt;&amp;lt;%= link_to &amp;quot;Edit Page&amp;quot;, &amp;quot;/editor&amp;quot; + request.path %&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;&lt;/pre&gt;

&lt;p&gt;When we reload the page now we&amp;rsquo;l see the two editable regions outlined in blue.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/825/original/E296I03.png" width="800" height="551" alt="The page now has editable regions."/&gt;
&lt;/div&gt;

&lt;h3&gt;Saving Changes&lt;/h3&gt;

&lt;p&gt;We can edit the two regions as much as we like now and preview our changes but we can&amp;rsquo;t save any changes we make as we haven&amp;rsquo;t yet set up our application to be able to do that. When we click the &amp;ldquo;Save&amp;rdquo; icon Mercury will pop up an alert showing where it was trying to save the changes to.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/826/original/E296I04.png" width="420" height="153" alt="Mercury show an alert if it can&amp;rsquo;t save changes to the server."/&gt;
&lt;/div&gt;

&lt;p&gt;The URL that Mercury tries to save to is the page&amp;rsquo;s URL. Mercury sends a POST request to this URL containing the changes. We&amp;rsquo;ll change this so that the updated content is sent to a new &lt;code&gt;mercury_update&lt;/code&gt; action on the &lt;code&gt;PagesController&lt;/code&gt;. We&amp;rsquo;ll need to modify the routes file so that it knows how to handle this new action.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/config/routes.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;Cms::Application.routes.draw do
  Mercury::Engine.routes

  root to: 'pages#index'
  resources :pages do
    member { post :mercury_update }
  end
end&lt;/pre&gt;

&lt;p&gt;Note that Mercury has added its own line to the routes file to enable the editor URL for each page.&lt;/p&gt;

&lt;p&gt;Next we&amp;rsquo;ll write the new &lt;code&gt;mercury_update&lt;/code&gt; action. This will need to find a page by its &lt;code&gt;id&lt;/code&gt; then update it and return a response. For now we&amp;rsquo;ll just put a placeholder comment where the update code will go.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/controllers/pages_controller.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;def mercury_update
  page = Page.find(params[:id])
  # Update page
  render text: &amp;quot;&amp;quot;
end&lt;/pre&gt;

&lt;p&gt;Now we need to tell Mercury that we&amp;rsquo;re not using its default URL for updating edited pages. Rather than hard-code this in JavaScript we&amp;rsquo;ll define it in a &lt;code&gt;data&lt;/code&gt; attribute it the &amp;ldquo;Edit Page&amp;rdquo; link. We&amp;rsquo;ll also give the link an &lt;code&gt;id&lt;/code&gt; now so that we can access it from JavaScript.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/pages/show.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;p&amp;gt;&amp;lt;%= link_to &amp;quot;Edit Page&amp;quot;, &amp;quot;/editor&amp;quot; + request.path, id: &amp;quot;edit_link&amp;quot;, data: { save_url: mercury_update_page_path(@page) } %&amp;gt;&amp;lt;/p&amp;gt;&lt;/pre&gt;

&lt;p&gt;We can tell Mercury about this URL at the bottom of the &lt;code&gt;mercury.js&lt;/code&gt; configuration file by adding the following code.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/javascripts/mercury.js&lt;/p&gt;
&lt;pre class="ruby"&gt;$(window).bind(&amp;#x27;mercury:ready&amp;#x27;, function() {
  var link = $(&amp;#x27;#mercury_iframe&amp;#x27;).contents().find(&amp;#x27;#edit_link&amp;#x27;);
  Mercury.saveURL = link.data(&amp;#x27;save-url&amp;#x27;);
  link.hide();
});&lt;/pre&gt;

&lt;p&gt;This code binds to the &lt;code&gt;mercury:ready&lt;/code&gt; event and when that event fires it finds the &amp;ldquo;Edit Page&amp;rdquo; link and sets Mercury&amp;rsquo;s &lt;code&gt;saveURL&lt;/code&gt; to the value in the &lt;code&gt;data-save-url&lt;/code&gt; attribute we added to it. Mercury loads the content of the current page into an iframe so we have to fetch its contents and find the link through there. As this code is triggered when the page is put into edit mode we&amp;rsquo;ll add a line to hide the &amp;ldquo;Edit Page&amp;rdquo; link here, too.&lt;/p&gt;

&lt;p&gt;When we make some changes to the page now and try to save them the error message no longer shows which means that Mercury has submitted them to the server. If we look in the development log we&amp;rsquo;ll see that saving the page triggers the &lt;code&gt;mercury_update&lt;/code&gt; action and that it has submitted a JSON string containing all the attributes necessary to update our &lt;code&gt;Page&lt;/code&gt; model.&lt;/p&gt;


&lt;pre class="terminal"&gt;Started POST &amp;quot;/pages/1/mercury_update&amp;quot; for 127.0.0.1 at 2011-11-10 18:31:59 +0000
  Processing by PagesController#mercury_update as JSON
  Parameters: {&amp;quot;content&amp;quot;=&amp;gt;&amp;quot;{\&amp;quot;page_name\&amp;quot;:{\&amp;quot;type\&amp;quot;:\&amp;quot;editable\&amp;quot;,\&amp;quot;value\&amp;quot;:\&amp;quot;Welcome!!\&amp;quot;,\&amp;quot;snippets\&amp;quot;:{}},\&amp;quot;page_content\&amp;quot;:{\&amp;quot;type\&amp;quot;:\&amp;quot;editable\&amp;quot;,\&amp;quot;value\&amp;quot;:\&amp;quot;&amp;lt;p&amp;gt;In this ASCIIcasts&amp;amp;nbsp;episode we are going to look at the &amp;lt;a href=\\\&amp;quot;http://jejacks0n.github.com/mercury/\\\&amp;quot;&amp;gt;Mercury Editor&amp;lt;/a&amp;gt;. It allows you to edit a document in-place, right in the HTML. It works in the following browsers.&amp;lt;/p&amp;gt;\\n&amp;lt;ul&amp;gt;\\n  &amp;lt;li&amp;gt;Firefox 4+&amp;lt;/li&amp;gt;\\n  &amp;lt;li&amp;gt;Chrome 10+&amp;lt;/li&amp;gt;\\n  &amp;lt;li&amp;gt;Safari 5+&amp;lt;/li&amp;gt;\\n&amp;lt;/ul&amp;gt;\\n&amp;lt;p&amp;gt;Try it out here by clicking on the &amp;lt;strong&amp;gt;&amp;lt;em&amp;gt;Edit Page&amp;lt;/em&amp;gt;&amp;lt;/strong&amp;gt; link below. There you will be able to change this page content and even the title above.&amp;lt;/p&amp;gt;\&amp;quot;,\&amp;quot;snippets\&amp;quot;:{}}}&amp;quot;, &amp;quot;id&amp;quot;=&amp;gt;&amp;quot;1&amp;quot;}&lt;/pre&gt;
  
&lt;p&gt;Mercury has the option to save the data as nested form parameters instead of by using JSON. To set this option we need to modify the &lt;code&gt;mercury.html.erb&lt;/code&gt; file that was  generated when we ran the Mercury generator. This file contains an &lt;code&gt;options&lt;/code&gt; object with a &lt;code&gt;saveStyle&lt;/code&gt; property. By default this property has a value of &lt;code&gt;null&lt;/code&gt; which means that JSON will be used when a page update is sent back to the server. We&amp;rsquo;ll change this to &lt;code&gt;&amp;#x27;form&amp;#x27;&lt;/code&gt;.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/layouts/mercury.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;
  var saveUrl = null;
  var options = {
    saveStyle: &amp;#x27;form&amp;#x27;,  // &amp;#x27;form&amp;#x27;, or &amp;#x27;json&amp;#x27; (default json)
    saveMethod: null, // &amp;#x27;POST&amp;#x27;, or &amp;#x27;PUT&amp;#x27;, (create, vs. update -- default POST)
    visible: null     // if the interface should start visible or not (default true)
  };
  new Mercury.PageEditor(saveUrl, options);
&amp;lt;/script&amp;gt;&lt;/pre&gt;

&lt;p&gt;When we save the changes to a page now they&amp;rsquo;re sent as nested parameters rather than as JSON data and we can use this data to save the changes to the database. The page&amp;rsquo;s name and content are both nested under the &lt;code&gt;content&lt;/code&gt; parameter and each of these has a &lt;code&gt;value&lt;/code&gt; property. We need these to save the page&amp;rsquo;s new content back to the database.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/controllers/pages_controller.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;def mercury_update
  page = Page.find(params[:id])
  page.name = params[:content][:page_name][:value]
  page.content = params[:content][:page_content][:value]
  page.save!
  render text: &amp;quot;&amp;quot;
end&lt;/pre&gt;

&lt;p&gt;When we change the page now and save the changes nothing appears to happen but when we go back to the page we&amp;rsquo;ll see that the changes have been saved.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/827/original/E296I05.png" width="800" height="280" alt="The changes are now saved."/&gt;
&lt;/div&gt;

&lt;p&gt;We want our application to redirect back to the page once we&amp;rsquo;ve saved the changes and we can do that by listening for the &lt;code&gt;mercury:saved&lt;/code&gt; event and redirecting when it fires.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/javascripts/mercury.js&lt;/p&gt;
&lt;pre class="javascript"&gt;$(window).bind(&amp;#x27;mercury:saved&amp;#x27;, function() {
  window.location = window.location.href.replace(/\/editor\//i, &amp;#x27;/&amp;#x27;);
});&lt;/pre&gt;


&lt;p&gt;Now when we save changes we&amp;rsquo;re redirected back to the page itself.&lt;/p&gt;

&lt;h3&gt;Going Further&lt;/h3&gt;

&lt;p&gt;There&amp;rsquo;s much more to Mercury than we can cover here. Reading through the comments in the &lt;code&gt;mercury.js&lt;/code&gt; file will give you a good idea as to what is possible. For example we can customize exactly what appears in the toolbar; there are various features like snippets, history and notes that we can enable and a whole lot more. All of these are documented in &lt;code&gt;mercury.js&lt;/code&gt;.&lt;/p&gt; 

&lt;p&gt;That&amp;rsquo;s it for our look at Mercury. It&amp;rsquo;s a great project and a lot of fun to use. If you want to add it to one of your Rails projects, though, bear in mind that you&amp;rsquo;ll need a modern version of Firefox, Chrome or Safari to use it.&lt;/p&gt;
</description>
      <pubDate>Thu, 10 Nov 2011 23:21:33 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/296-mercury-editor</guid>
      <link>http://asciicasts.com/episodes/296-mercury-editor</link>
    </item>
    <item>
      <title>Playing With PJAX</title>
      <description>&lt;p&gt;Pjax is a jQuery plugin, written by Chris Wanstrath, that allows you to easily update a section of a page with an AJAX request instead of having to do a full HTTP request. The demo page1 shows how this works. By default, clicking on any of the links on this page will cause the page to fully reload and we can tell that this has happened as the time on the page changes. When we enable pjax by clicking the checkbox clicking the links no longer reload a full page and the time no longer updates, although the main section of the page still changes.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/803/original/E294I01.png" width="800" height="531" alt="The pjax demo site."/&gt;
&lt;/div&gt;

&lt;p&gt;Pjax uses pushState so the user won&amp;rsquo;t notice that AJAX requests are being made in the background. Each time pjax updates the page the URL in the address bar updates, the page&amp;rsquo;s title changes and the previous page is added to the browser&amp;rsquo;s history so that the back button works correctly. Pjax degrades gracefully too: if the user&amp;rsquo;s browser doesn&amp;rsquo;t support pushState or they&amp;rsquo;ve disabled JavaScript it will fall back to making a traditional HTTP request.&lt;/p&gt;

&lt;h3&gt;Integrating Pjax into a Rails Application&lt;/h3&gt;

&lt;p&gt;There are several ways we can integrate pjax into a Rails application and we&amp;rsquo;ll try two of them in this episode. The application we&amp;rsquo;ll be working with is shown below. It shows a list of products and clicking on a product reveals a sidebar showing some information about that product.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/804/original/E294I02.png" width="799" height="531" alt="Our site showing the information for one of the products."/&gt;
&lt;/div&gt;

&lt;p&gt;Currently when we click on the link the entire page reloads. To show how much of the page has changed the layout file and the page&amp;rsquo;s template both generate random numbers when they&amp;rsquo;re loaded. When both numbers change this shows that the entire page has been reloaded and this is what we currently see. We&amp;rsquo;ll use pjax now so that only the areas of the page that need to change are updated.&lt;/p&gt;

There&amp;rsquo;s a gem called &lt;a href="https://github.com/rails/pjax_rails"&gt;pjax_rails&lt;/a&gt; by David Heinemeier Hansson that makes it easy to add pjax to a Rails 3.1 application and though it doesn&amp;rsquo;t quite fit the needs of our application we&amp;rsquo;ll try it anyway to show how it works. To install it we just add the pjax_rails gem to our &lt;code&gt;/Gemfile&lt;/code&gt; and run &lt;code&gt;bundle&lt;/code&gt;.

&lt;p class="codeFilePath"&gt;/Gemfile&lt;/p&gt;
&lt;pre class="ruby"&gt;source &amp;#x27;http://rubygems.org&amp;#x27;

gem &amp;#x27;rails&amp;#x27;, &amp;#x27;3.1.1&amp;#x27;
gem &amp;#x27;sqlite3&amp;#x27;

# Gems used only for assets and not required
# in production environments by default.
group :assets do
  gem &amp;#x27;sass-rails&amp;#x27;,   &amp;#x27;~&amp;gt; 3.1.4&amp;#x27;
  gem &amp;#x27;coffee-rails&amp;#x27;, &amp;#x27;~&amp;gt; 3.1.1&amp;#x27;
  gem &amp;#x27;uglifier&amp;#x27;, &amp;#x27;&amp;gt;= 1.0.3&amp;#x27;
end

gem &amp;#x27;jquery-rails&amp;#x27;
gem &amp;#x27;pjax_rails&amp;#x27;&lt;/pre&gt;

&lt;p&gt;Once Bundler has finished we need to modify our &lt;code&gt;application.js&lt;/code&gt; manifest file so that it loads pjax&amp;rsquo;s JavaScript.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/assets/javascripts/application.js&lt;/p&gt;
&lt;pre class="javascript"&gt;// This is a manifest file that&amp;#x27;ll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they&amp;#x27;ll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It&amp;#x27;s not advisable to add code directly here, but if you do, it&amp;#x27;ll appear at the bottom of the
// the compiled file.
//
//= require jquery
//= require jquery_ujs
//= require pjax
//= require_tree .&lt;/pre&gt;

&lt;p&gt;Finally we need to wrap the &lt;code&gt;yield&lt;/code&gt; call in the layout file in a div with a &lt;code&gt;data-pjax-container&lt;/code&gt; attribute.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/layouts/application.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;&amp;lt;%= content_for?(:title) ? content_for(:title) : &amp;quot;Store&amp;quot; %&amp;gt;&amp;lt;/title&amp;gt;
    &amp;lt;%= stylesheet_link_tag    &amp;quot;application&amp;quot; %&amp;gt;
    &amp;lt;%= javascript_include_tag &amp;quot;application&amp;quot; %&amp;gt;
    &amp;lt;%= csrf_meta_tag %&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;div id=&amp;quot;container&amp;quot;&amp;gt;
      &amp;lt;div class=&amp;quot;layout_time&amp;quot;&amp;gt;Layout random: &amp;lt;strong&amp;gt;&amp;lt;%= rand(900)+100 %&amp;gt;&amp;lt;/strong&amp;gt;&amp;lt;/div&amp;gt;
      &amp;lt;% flash.each do |name, msg| %&amp;gt;
        &amp;lt;%= content_tag :div, msg, :id =&amp;gt; &amp;quot;flash_#{name}&amp;quot; %&amp;gt;
      &amp;lt;% end %&amp;gt;
      &amp;lt;div data-pjax-container&amp;gt;
      &amp;lt;%= yield %&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/pre&gt;

&lt;p&gt;When we restart the server and reload our page now every link on the page will be pjax-enabled. When we click a link now the page doesn&amp;rsquo;t reload fully and we can see this as only the template&amp;rsquo;s random number changes. This is almost what we want but if we look closely we&amp;rsquo;ll see that the page&amp;rsquo;s title doesn&amp;rsquo;t change when we click on one of the links.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/805/original/E294I03.png" width="799" height="411" alt="The title doesn't change when the rest of the page does."/&gt;
&lt;/div&gt;

&lt;p&gt;We can fix this by adding a &lt;code&gt;title&lt;/code&gt; tag in the template. This is a little hacky and makes the page&amp;rsquo;s HTML invalid, but it does work.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/index.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;% content_for :title, @product ? @product.name : &amp;quot;Products&amp;quot; %&amp;gt;
&amp;lt;title&amp;gt;&amp;lt;%= yield (:title) %&amp;gt;&amp;lt;/title&amp;gt;
&amp;lt;!-- Rest of page omitted --&amp;gt;&lt;/pre&gt;


&lt;p&gt;When we reload the page now the title changes when we click one of the links and we also have a fully-working back button and history. From the user&amp;rsquo;s perspective everything works as it did before but it feels a little faster. This is good but the &lt;code&gt;pjax_rails&lt;/code&gt; gem is a little aggressive. Every link on the page is pjax-enabled by default but this isn&amp;rsquo;t really what we want in our application. Likewise the whole template is always updated when we click a link and there&amp;rsquo;s no way of restricting which parts of the page are updated. There is a way of disabling pjax for certain links but having to keep track of these can be awkward. If you have a simple application whose layout file always stays the same, though, then pjax-rails may well suit you, though.&lt;/p&gt;

&lt;p&gt;It should be possible to use Rack middleware to make a more flexible solution and this is how Gert Goet&amp;rsquo;s  &lt;a href="https://github.com/eval/rack-pjax"&gt;rack-pjax&lt;/a&gt; gem works so we&amp;rsquo;ll replace pjax_rails with rack-pjax in our application. First we&amp;rsquo;ll replace the pjax_rails gem with rack-pjax in the &lt;code&gt;Gemfile&lt;/code&gt; and run &lt;code&gt;bundle&lt;/code&gt; again.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/Gemfile&lt;/p&gt;
&lt;pre class="ruby"&gt;# gem &amp;#x27;pjax_rails&amp;#x27;
gem &amp;#x27;rack-pjax&lt;/pre&gt;

&lt;p&gt;Next we need to add the included Rack middleware to the application&amp;rsquo;s config file.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/config/application.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;module Store
  class Application &amp;lt; Rails::Application 
    config.middleware.use Rack::Pjax
    # Other config commands omitted
  end
end&lt;/pre&gt;

&lt;p&gt;Rack-pjax doesn&amp;rsquo;t come with a jQuery plugin embedded so we&amp;rsquo;ll need to install this separately. We&amp;rsquo;ll create a &lt;code&gt;vendor/assets/javascripts&lt;/code&gt; directory in our application and download the &lt;code&gt;jquery.pjax.js&lt;/code&gt; file to it using &lt;code&gt;curl&lt;/code&gt;.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;terminal&lt;/p&gt;
&lt;pre class="ruby"&gt;$ mkdir -p vendor/assets/javascripts
$ curl https://raw.github.com/defunkt/jquery-pjax/master/jquery.pjax.js &amp;gt; vendor/assets/javascripts/jquery.pjax.js&lt;/pre&gt;

&lt;p&gt;We&amp;rsquo;ll need to include this file in our application&amp;rsquo;s JavaScript manifest file so we&amp;rsquo;ll replace pjax_rails&amp;rsquo;s JavaScript file with this one.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/assets/javascripts/application.js&lt;/p&gt;
&lt;pre class="javascript"&gt;//= require jquery
//= require jquery_ujs
//= require jquery.pjax
//= require_tree .&lt;/pre&gt;

&lt;p&gt;Unlike pjax_rails, rack-pjax doesn&amp;rsquo;t pjax-enable all links by default so we need to specify the ones to enable. These are all in pages in the &lt;code&gt;ProductsController&lt;/code&gt; so we&amp;rsquo;ll do this in the products CoffeeScript file.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/javascripts/products.js.coffee&lt;/p&gt;
&lt;pre class="javascript"&gt;jQuery -&amp;gt;
  $(&amp;#x27;.product a&amp;#x27;).pjax(&amp;#x27;[data-pjax-container]&amp;#x27;)&lt;/pre&gt;

&lt;p&gt;In this code we first make sure that the DOM has loaded then fetch the links that we want to enable. In our case this is any link inside a parent element with a &lt;code&gt;product&lt;/code&gt; class. We then call &lt;code&gt;pjax&lt;/code&gt; on them and specify what we want to update when the link is clicked.&lt;/p&gt;

&lt;p&gt;With rack-pjax we no longer need to override the &lt;code&gt;title&lt;/code&gt; element and so we can remove this from the &lt;code&gt;index&lt;/code&gt; template. When we reload the page now it works as it did before; the template is updated when we click a link but not the layout and only the template&amp;rsquo;s random number is updated. The title is updated now, too, even though it&amp;rsquo;s not specified in the template because this is detected from the layout.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/806/original/E294I04.png" width="799" height="411" alt="The title is now updated correctly."/&gt;
&lt;/div&gt;

&lt;p&gt;What&amp;rsquo;s really useful is that we can now move our &lt;code&gt;data-pjax-container&lt;/code&gt; element anywhere we want. It no longer has to be placed around the &lt;code&gt;yield&lt;/code&gt; call in the layout file. We&amp;rsquo;ll move it into the &lt;code&gt;index&lt;/code&gt; template and wrap it around the product details section, i.e. the section that displays the details for a product.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/products/index.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;% content_for :title, @product ? @product.name : &amp;quot;Products&amp;quot; %&amp;gt;

&amp;lt;div class=&amp;quot;template_time&amp;quot;&amp;gt;Template random: &amp;lt;strong&amp;gt;&amp;lt;%= rand(900)+100 %&amp;gt;&amp;lt;/strong&amp;gt;&amp;lt;/div&amp;gt;

&amp;lt;h1&amp;gt;Products&amp;lt;/h1&amp;gt;

&amp;lt;% for product in @products %&amp;gt;
  &amp;lt;div class=&amp;quot;product&amp;quot;&amp;gt;
    &amp;lt;h2&amp;gt;
      &amp;lt;%= link_to product.name, :product_id =&amp;gt; product %&amp;gt;
      &amp;lt;span class=&amp;quot;price&amp;quot;&amp;gt;&amp;lt;%= number_to_currency(product.price) %&amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;/h2&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;% end %&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;%= link_to &amp;quot;New Product&amp;quot;, new_product_path %&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;div data-pjax-container&amp;gt;
  &amp;lt;% if @product %&amp;gt;
  &amp;lt;div id=&amp;quot;product_details&amp;quot;&amp;gt;
    &amp;lt;h3&amp;gt;&amp;lt;%= @product.name %&amp;gt;&amp;lt;/h3&amp;gt;
    &amp;lt;dl&amp;gt;
      &amp;lt;dt&amp;gt;Price:&amp;lt;/dt&amp;gt;
      &amp;lt;dd&amp;gt;&amp;lt;%= number_to_currency(@product.price) %&amp;gt;&amp;lt;/dd&amp;gt;
      &amp;lt;dt&amp;gt;Released:&amp;lt;/dt&amp;gt;
      &amp;lt;dd&amp;gt;&amp;lt;%= @product.released_at.strftime(&amp;quot;%B %e, %Y&amp;quot;) %&amp;gt;&amp;lt;/dd&amp;gt;
      &amp;lt;dt&amp;gt;Category:&amp;lt;/dt&amp;gt;
      &amp;lt;dd&amp;gt;&amp;lt;%= @product.category %&amp;gt;&amp;lt;/dd&amp;gt;
    &amp;lt;/dl&amp;gt;
    &amp;lt;p class=&amp;quot;actions&amp;quot;&amp;gt;
      &amp;lt;%= link_to &amp;quot;Edit&amp;quot;, edit_product_path(@product) %&amp;gt; |
      &amp;lt;%= link_to &amp;quot;Destroy&amp;quot;, @product, method: :delete, confirm: &amp;quot;Are you sure?&amp;quot; %&amp;gt;
    &amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;% end %&amp;gt;
&amp;lt;/div&amp;gt;&lt;/pre&gt;
&lt;p&gt;Now when we click a link only the side panel changes and neither of the random numbers changes.&lt;/p&gt;

&lt;p&gt;If you&amp;rsquo;re curious about how this gem works then you should take a look at its source code. It&amp;rsquo;s really simple, being just one Ruby file of about fifty lines of code. Bear in mind though that the entire layout and template are still rendered by the server before rack-pjax decides which parts to send back to the client. If rendering the template is a big performance problem then you might be better off looking at an alternative solution, but for most application this should work perfectly.&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s it for our episode on pjax. It&amp;rsquo;s a simple solution and well worth taking a look at if you think it might fit your application&amp;rsquo;s needs.&lt;/p&gt;</description>
      <pubDate>Thu, 10 Nov 2011 23:04:12 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/294-playing-with-pjax</guid>
      <link>http://asciicasts.com/episodes/294-playing-with-pjax</link>
    </item>
  </channel>
</rss>

