<?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, 29 Jan 2012 18:05:13 +0000</pubDate>
    <ttl>1440</ttl>
    <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>
    <item>
      <title>Virtual Machines with Vagrant</title>
      <description>&lt;p&gt;As a Rails developer you&amp;rsquo;ll often find that your development environment is quite different from the production environment. Indeed it&amp;rsquo;s not unusual to develop an application on a different operating system from the one it will run on in production. Rails applications can also have a heavy set of dependencies that can be difficult to replicate across different machines.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://vagrantup.com/"&gt;Vagrant&lt;/a&gt; can help with this. It allows us to set up and manage virtual environments so we can set up a small Linux distribution inside our OS and run our application and all of its dependencies on a virtual machine that we can save to a portable package that we be easily shared with others.&lt;/p&gt; 

&lt;p&gt;Every Rails developer give Vagrant a try. At the least it will give you a better understanding of how to set up a production environment for your Rails apps. It&amp;rsquo;s also useful to use to set up a staging environment or even while developing an app.&lt;/p&gt;

&lt;h3&gt;Installing Virtual Box and Vagrant&lt;/h3&gt;

&lt;p&gt;Vagrant uses Oracle&amp;rsquo;s &lt;a href="https://www.virtualbox.org/"&gt;VirtualBox&lt;/a&gt;. If you don&amp;rsquo;t have it installed on your machine you&amp;rsquo;ll need to install it first. VirtualBox is available for Windows, OS X and Linux so whatever OS you&amp;rsquo;re running you should be able to find a suitable version. Once we&amp;rsquo;ve installed VirtualBox we can install Vagrant. This is a Ruby gem and we install it by running this command.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ gem install vagrant&lt;/pre&gt;

&lt;h3&gt;Adding a Box&lt;/h3&gt;

&lt;p&gt;The next step is to add a virtual machine, known as a  box to Vagrant. There&amp;rsquo;s a long list of publicly available boxes at &lt;a href="http://www.vagrantbox.es/"&gt;Vagrantbox.es&lt;/a&gt; and we can download one from there. We&amp;rsquo;ll use, ubuntu &lt;a href="http://www.vagrantbox.es/1/"&gt;lucid 32&lt;/a&gt;, which is provided by the Vagrant site and which is based on Ubuntu Linux 10.04. To install the box we run &lt;code&gt;vagrant box add&lt;/code&gt;, passing in a name and the URL of the box.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ vagrant box add lucid32 http://files.vagrantup.com/lucid32.box
[vagrant] Downloading with Vagrant::Downloaders::HTTP...
[vagrant] Downloading box: http://files.vagrantup.com/lucid32.box
[vagrant] Extracting box...
[vagrant] Verifying box...
[vagrant] Cleaning up downloaded box...&lt;/pre&gt;

&lt;p&gt;Boxes can be fairly large (in the order of a few hundred megabytes) so they can take a while to download. If you&amp;rsquo;ve already downloaded one you can pass in a file URL instead to install from a local box file.&lt;/p&gt;

&lt;p&gt;Once the box has downloaded and installed we can use it to set up our virtual environment. In Vagrant this is usually done for a specific project. We don&amp;rsquo;t have one so we&amp;rsquo;ll create a new one to work with, then move into its directory.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ rails new todo
$ cd todo&lt;/pre&gt;

&lt;p&gt;We can create a virtual machine just for this application and its dependencies by running &lt;code&gt;vagrant init&lt;/code&gt; and passing in the name of the box we want to use.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ vagrant init lucid32
      create  Vagrantfile&lt;/pre&gt;
      

&lt;p&gt;All this command does is create a file called &lt;code&gt;Vagrantfile&lt;/code&gt;. This file contains the configuration information for this application&amp;rsquo;s Vagrant box. By default all of the information is commented out, apart from the line that specifies which box to use.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/Vagrantfile&lt;/p&gt;
&lt;pre class="ruby"&gt;Vagrant::Config.run do |config|
  # All Vagrant configuration is done here. The most common configuration
  # options are documented and commented below. For a complete reference,
  # please see the online documentation at vagrantup.com.

  # Every Vagrant virtual environment requires a box to build off of.
  config.vm.box = "lucid32"

  # Rest of file omitted.
end&lt;/pre&gt;

&lt;p&gt;There are many other configuration options that we can specify here and its worth taking a minute to look through them all.&lt;/p&gt; 

&lt;h3&gt;Starting up The Vagrant VM&lt;/h3&gt;

&lt;p&gt;Now it&amp;rsquo;s time for the magic. Running &lt;code&gt;vagrant up&lt;/code&gt; will set up our virtual machine. This can take a few minutes but once it&amp;rsquo;s booted up we can SSH into it with&lt;/p&gt;

&lt;pre class="terminal"&gt;$ vagrant ssh&lt;/pre&gt;

&lt;p&gt;We&amp;rsquo;re now inside our Ubuntu virtual machine. This is a fairly barebones setup with very little installed on it, but there are a couple of things worthy of note. One is that it has a user called &lt;code&gt;vagrant&lt;/code&gt; set up (and which we&amp;rsquo;re logged in as), the other is that we have &lt;code&gt;sudo&lt;/code&gt; privileges that don&amp;rsquo;t require a password which is fine for our local development machine. Vagrant has also set up a shared directory at &lt;code&gt;/vagrant&lt;/code&gt; that points to the directory where we have our Rails application.&lt;/p&gt;

&lt;h3&gt;Installing Our Application&amp;rsquo;s Dependencies&lt;/h3&gt;

&lt;p&gt;Our objective is to get our Rails application up and running on our virtual machine so we&amp;rsquo;re doing to have to set up its dependencies. First we&amp;rsquo;ll make sure we have Ruby and Sqlite installed. Our virtual machine already has Ruby 1.8.7 installed which has been done so that it can run &lt;a href="http://wiki.opscode.com/display/chef/Home"&gt;Chef&lt;/a&gt; recipes.&lt;/p&gt;

&lt;p&gt;Chef provides a way to automate server setup. To install Ruby 1.9 and Sqlite we could apply the necessary Chef recipes and they will be installed for us. Chef integrates nicely with Vagrant but it&amp;rsquo;s a big topic in itself and is something we&amp;rsquo;ll cover in a future episode. Instead we&amp;rsquo;ll set up our server without using Chef which will give us a better idea of how everything works together.&lt;/p&gt;

&lt;p&gt;First we&amp;rsquo;ll use &lt;code&gt;apt-get&lt;/code&gt; to make sure that all of our installed software is up to date.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ sudo apt-get update&lt;/pre&gt;

&lt;p&gt;Once that has finished we&amp;rsquo;ll install some of the software we need: the build essentials, ZLib, Git and Sqlite3.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ sudo apt-get install build-essential zlib1g-dev git-core sqlite3 libsqlite3-dev&lt;/pre&gt; 

&lt;p&gt;All have left to install now is Ruby 1.9. We could install this from scratch or by using RVM but we&amp;rsquo;ll use something newer called &lt;a href="https://github.com/sstephenson/rbenv"&gt;rbenv&lt;/a&gt;. Using Vagrant means that we can experiment with tools such as this that we haven&amp;rsquo;t used before in a safe environment and, if we mess up, delete the virtual machine and start again.&lt;/p&gt;

&lt;p&gt;To install rbenv in our virtual machine we just run the commands listed in section 2.1 of rbenv&amp;rsquo;s &lt;a href="https://github.com/sstephenson/rbenv/blob/master/README.md"&gt;README&lt;/a&gt;. First we clone the repository into &lt;code&gt;~/.rbenv&lt;/code&gt;.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ cd
$ git clone git://github.com/sstephenson/rbenv.git .rbenv&lt;/pre&gt;

&lt;p&gt;Next we add rbenv&amp;rsquo;s &lt;code&gt;bin&lt;/code&gt; directory to our PATH and add the init command to our bash profile.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ echo &amp;#x27;export PATH=&amp;quot;$HOME/.rbenv/bin:$PATH&amp;quot;&amp;#x27; &amp;gt;&amp;gt; ~/.bash_profile
$ echo &amp;#x27;eval &amp;quot;$(rbenv init -)&amp;quot;&amp;#x27; &amp;gt;&amp;gt; ~/.bash_profile&lt;/pre&gt;

&lt;p&gt;We&amp;rsquo;ll have to reload the bash profile for these changes to take effect.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ source .bash_profile &lt;/pre&gt;

&lt;p&gt;We now have an &lt;code&gt;rbenv&lt;/code&gt; command that we can use to manage our Ruby versions but still no way to install Ruby. We&amp;rsquo;ll use &lt;a href="https://github.com/sstephenson/ruby-build"&gt;Ruby Build&lt;/a&gt; to do this. All we need to do is clone its Git repository, then move into its directory and run its install script.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ git clone https://github.com/sstephenson/ruby-build.git
$ cd ruby-build
$ sudo ./install.sh&lt;/pre&gt;

&lt;p&gt;We can now use rbenv to install the current version of Ruby 1.9.2.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ rbenv install 1.9.2-p290&lt;/pre&gt;

&lt;p&gt;This will take a while to run but when it finishes it will have successfully compiled Ruby 1.9.2. We&amp;rsquo;ll need to run &lt;code&gt;rbenv rehash&lt;/code&gt; when ever we change the binaries like this and then we&amp;rsquo;ll run this command to make 1.9.2 the default version of Ruby on our virtual machine.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ rbenv global 1.9.2-p290&lt;/pre&gt;

&lt;p&gt;When we check our version of Ruby now it&amp;rsquo;s 1.9.2 just like we want.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ ruby -v
ruby 1.9.2p290 (2011-07-09 revision 32553) [i686-linux]&lt;/pre&gt;

&lt;h3&gt;Installing Our Rails Application&lt;/h3&gt;

&lt;p&gt;Now that we have the correct version of Ruby installed we can work on getting our Rails application working. If we move to the shared directory our application is in and run bundle to install its dependencies we&amp;rsquo;ll hit a problem.&lt;/p&gt;

&lt;pre class="terminal"&gt;vagrant@lucid32:~$ cd /vagrant/
vagrant@lucid32:/vagrant$ bundle
bundle: command not found&lt;/pre&gt;

&lt;p&gt;All we need to do to fix this is install the Bundler gem.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ gem install bundler&lt;/pre&gt;

&lt;p&gt;Once this gem has installed we&amp;rsquo;ll need to run &lt;code&gt;rbenv rehash&lt;/code&gt; again to set up the &lt;code&gt;bundle&lt;/code&gt; executable. We can now run &lt;code&gt;bundle&lt;/code&gt; to install our application&amp;rsquo;s gems.&lt;/p&gt;

&lt;p&gt;If we try to start our application&amp;rsquo;s server now, it will throw a error complaining that it couldn&amp;rsquo;t find a JavaScript runtime. This makes sense as Rails 3.1 requires a JavaScript runtime and Ubuntu doesn&amp;rsquo;t have one by default. The quick solution to this is to add a gem called &lt;a href="https://github.com/cowboyd/therubyracer"&gt;therubyracer&lt;/a&gt; to our application&amp;rsquo;s Gemfile and run bundle on our virtual machine. This will install the V8 JavaScript engine.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/Gemfile&lt;/p&gt;
&lt;pre class="ruby"&gt;gem 'therubyracer'&lt;/pre&gt;

&lt;p&gt;Once the gem has installed we can try running our server again.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ bundle exec rails s&lt;/pre&gt;

&lt;p&gt;This time it starts successfully and our application is up and running on port 3000. We can&amp;rsquo;t view it in a browser, though, as it&amp;rsquo;s running on the virtual machine. We have to tell Vagrant to forward the port to our machine and we do this by modifying our project&amp;rsquo;s &lt;code&gt;Vagrantfile&lt;/code&gt;. We need to uncomment the line below, change the name to something more suitable tell it to forward port 3000 on the virtual machine to the same port on our local machine.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/Vagrantfile&lt;/p&gt;
&lt;pre class="ruby"&gt;config.vm.forward_port "rails", 3000, 3000&lt;/pre&gt;

&lt;p&gt;Having changed the configuration we&amp;rsquo;ll need to exit out of our Vagrant shell by running &lt;code&gt;exit&lt;/code&gt; in the VM and then reload the virtual machine by running &lt;code&gt;vagrant reload&lt;/code&gt;. This will shutdown our virtual machine and then reload it. Once it&amp;rsquo;s reloaded we can SSH into it again.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ vagrant ssh&lt;/pre&gt;

&lt;p&gt;Then on the virtual machine we can move to our application&amp;rsquo;s directory and start up the server again.&lt;/p&gt;

&lt;pre class="terminal"&gt;vagrant@lucid32:~$ cd /vagrant
vagrant@lucid32:/vagrant$ bundle exec rails s&lt;/pre&gt;

&lt;p&gt;This boots up the server again but we can now access it from our local machine.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/794/original/E292I01.png" width="829" height="361" alt="Our application running under Vagrant."/&gt;
&lt;/div&gt;

&lt;p&gt;As our Rails application is shared with Vagrant any changes we make to it will be reflected in our virtual machine. If we modify the default page at &lt;code&gt;/public/index.html&lt;/code&gt;  and reload the page the changes will be shown immediately.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/public/index.html&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;h2&amp;gt;You&amp;amp;rsquo;re riding Ruby on Rails on Vagrant!&amp;lt;/h2&amp;gt;&lt;/pre&gt;
&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/795/original/E292I02.png" width="829" height="361" alt="Any changes we make are reflected when we reload the page."/&gt;
&lt;/div&gt;

&lt;h3&gt;Other Vagrant Commands&lt;/h3&gt;

&lt;p&gt;Vagrant provides a number of commands to help us manage our virtual machine. To get the current status of our VM we can run &lt;code&gt;vagrant status&lt;/code&gt;.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ vagrant status
Current VM states:

default                  running

The VM is running. To stop this VM, you can run `vagrant halt` to
shut it down forcefully, or you can run `vagrant suspend` to simply
suspend the virtual machine. In either case, to restart it again,
simply run `vagrant up`.&lt;/pre&gt;

&lt;p&gt;To temporarily stop and restart the machine we can use &lt;code&gt;suspend&lt;/code&gt; and &lt;code&gt;resume&lt;/code&gt;.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ vagrant suspend
[default] Saving VM state and suspending execution...

$ vagrant resume
[default] Resuming suspended VM...
[default] Booting VM...
[default] Waiting for VM to boot. This can take a few minutes.
[default] VM booted and ready for use!&lt;/pre&gt;

&lt;p&gt;To complete shut down the VM we can use &lt;code&gt;vagrant halt&lt;/code&gt;. We&amp;rsquo;ll then need to use &lt;code&gt;vagrant up&lt;/code&gt; again to bring that machine back up.&lt;/p&gt;

&lt;p&gt;One of the most useful commands is &lt;code&gt;vagrant package&lt;/code&gt;. This will package up the virtual machine in its current state into a file called &lt;code&gt;package.box&lt;/code&gt;. We can then share and distribute this file or use it to quickly recreate our virtual machine. If we use &lt;code&gt;vagrant destroy&lt;/code&gt; to delete our virtual machine we can then restore it with the same &lt;code&gt;vagrant box add&lt;/code&gt; command we used to set up our virtual machine in the first place.&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s it for our episode on Vagrant. It&amp;rsquo;s a great solution for taking your Rails apps&amp;rsquo; runtime dependencies and isolating them in a virtualized environment that can be packaged up and distributed among other developers, used to simulate the production server or used as a staging server. Vagrant becomes even more useful when used in combination with Chef and we&amp;rsquo;ll be covering that in a future episode.&lt;/p&gt;</description>
      <pubDate>Sun, 30 Oct 2011 10:54:48 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/292-virtual-machines-with-vagrant</guid>
      <link>http://asciicasts.com/episodes/292-virtual-machines-with-vagrant</link>
    </item>
    <item>
      <title>SOAP With Savon</title>
      <description>&lt;p&gt;There comes a time in every web developer&amp;rsquo;s life when they have to communicate with a SOAP API; when simple Ruby code needs to talk with complex .Net and Java applications. Thankfully there&amp;rsquo;s help for this potentially unpleasant task. &lt;a href="http://savonrb.com/"&gt;Savon&lt;/a&gt; is a Ruby gem written by Daniel Harrington that provides a nice Ruby interface for communicating with SOAP APIs. In this episode we&amp;rsquo;ll show you how it works.&lt;/p&gt;

&lt;h3&gt;ZipCode Lookups&lt;/h3&gt;

&lt;p&gt;Below is a page from an application with a simple form that takes a Zip code. We want users to be able to enter a Zip code and have information it returned.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/786/original/E290I01.png" width="800" height="388" alt="Our Zip code lookup application."/&gt;
&lt;/div&gt;

&lt;p&gt;As you can see our application doesn&amp;rsquo;t work yet. We have placeholders for the information but nothing is shown as we need to communicate with an external Web Service to get this information. We&amp;rsquo;ll get this information from the &lt;a href="http://www.webservicex.net/ws/default.aspx"&gt;WebserviceX.NET website&lt;/a&gt;. This site has a SOAP API that can provide a lot of useful information such as stock market quotes, currency conversion, weather information and a whole lot more and we&amp;rsquo;ll use it to fetch information about a Zip code. The site has a &lt;a href="http://www.webservicex.net/ws/WSDetails.aspx?WSID=42&amp;amp;CATID=7"&gt;page&lt;/a&gt; with a form we can use to test the web service. If we enter a valid zip code in the form we&amp;rsquo;ll set some XML returned containing data about that Zip code. If, for example, we enter 90210 we&amp;rsquo;ll get this response.&lt;/p&gt;


&lt;pre class="terminal"&gt;
&amp;lt;NewDataSet&amp;gt;
  &amp;lt;Table&amp;gt;
    &amp;lt;CITY&amp;gt;Beverly Hills&amp;lt;/CITY&amp;gt;
    &amp;lt;STATE&amp;gt;CA&amp;lt;/STATE&amp;gt;
    &amp;lt;ZIP&amp;gt;90210&amp;lt;/ZIP&amp;gt;
    &amp;lt;AREA_CODE&amp;gt;310&amp;lt;/AREA_CODE&amp;gt;
    &amp;lt;TIME_ZONE&amp;gt;P&amp;lt;/TIME_ZONE&amp;gt;
  &amp;lt;/Table&amp;gt;
&amp;lt;/NewDataSet&amp;gt;
&lt;/pre&gt;

&lt;h3&gt;Using soapUI To Test SOAP calls&lt;/h3&gt;

&lt;p&gt;Before we jump right in and use a SOAP API in an application it&amp;rsquo;s a good idea to experiment with it a little to make sure that it works the way we expect it to. To help with this we&amp;rsquo;ll use a Java application called &lt;a href="http://www.eviware.com/soapUI/soapui-products-overview.html"&gt;soapUI&lt;/a&gt; that we can use to test Web Services. Once we&amp;rsquo;ve installed it we can run it and create a new project. When we do we&amp;rsquo;ll be shown a dialog box that asks for a WSDL URL, among other things. The page we viewed before has this information and the URL we need to enter is &lt;code&gt;http://www.webservicex.net/uszip.asmx?WSDL&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A WSDL is like a blueprint and it tells us they actions that are available at that URL. Once we&amp;rsquo;ve entered the WSDL URL into soapUI we&amp;rsquo;ll see a list of the actions. If we expand the GetInfoByZip action and click the &amp;ldquo;Request 1&amp;rdquo; field that&amp;rsquo;s revealed we&amp;rsquo;ll see the XML that&amp;rsquo;s required for making a request.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/787/original/E290I02.png" width="812" height="434" alt="The request XML showing in soapUI."/&gt;
&lt;/div&gt;

&lt;p&gt;This is the information we need to get from soapUI so that we can compare it to Savon as we use it in our Rails application. If we replace the question mark in the &lt;code&gt;&amp;lt;web:USZip&amp;gt;&lt;/code&gt; element with a real Zip code and click the green arrow we see the XML response.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/788/original/E290I03.png" width="812" height="434" alt="The response XML in soapUI."/&gt;
&lt;/div&gt;

&lt;h3&gt;Getting Started With Savon&lt;/h3&gt;

&lt;p&gt;Now that we have a way of testing SOAP requests we can start using Savon in our application. As is usual when installing a gem we do this by adding the gem to the Gemfile and then running bundle.
&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;savon&amp;#x27;
&lt;/pre&gt;

&lt;p&gt;To get a feel for how Savon works we&amp;rsquo;ll experiment with it in the console. The first thing we need to do is create a new Savon::Client, passing it the URL we want to to communicate with.&lt;/p&gt;

&lt;pre class="terminal"&gt;
&amp;gt; client = Savon::Client.new(&amp;quot;http://www.webservicex.net/uszip.asmx?WSDL&amp;quot;)
&lt;/pre&gt;

&lt;p&gt;We can provide a block here if we want to provide additional configuration, but for our purposes this is enough. Next we&amp;rsquo;ll get a list of the actions.&lt;/p&gt;

&lt;pre class="terminal"&gt;
&amp;gt; client.wsdl.soap_actions
HTTPI executes HTTP GET using the net_http adapter =&amp;gt; [:get_info_by_zip, :get_info_by_city, :get_info_by_state, :get_info_by_area_code]
&lt;/pre&gt;
    
&lt;p&gt;One of the actions that is returned is just the one we&amp;rsquo;re looking for. (Note that Savon has changed the name from &lt;code&gt;GetInfoByZip&lt;/code&gt; to the more Ruby-like &lt;code&gt;get_info_by_zip&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;We make a request by calling &lt;code&gt;client.request&lt;/code&gt; and passing in the action we want to call. We can also pass in a namespace as an optional first argument. If we look at the XML that was generated by soapUI we&amp;rsquo;ll see that a &lt;code&gt;web&lt;/code&gt; namespace is used so we&amp;rsquo;ll need to pass that in. Finally we&amp;rsquo;ll need to add some options. Again, we could  use a block here, but instead we&amp;rsquo;ll pass in a &lt;code&gt;body&lt;/code&gt; option. This option takes a hash and it&amp;rsquo;s here where we pass the parameters in that we saw in the XML request. In soapUI the Zip code was passed in in a &lt;code&gt;&amp;lt;web:USZip&amp;gt;&lt;/code&gt; element. We&amp;rsquo;ve already specified the namespace so we just need to pass in the Zip code as &lt;code&gt;us_zip&lt;/code&gt;. (Again, Savon changes the capitalization of the parameter.&lt;/p&gt;

&lt;pre class="terminal"&gt;
&amp;gt; client.request :web, :get_info_by_zip, body: { us_zip: &amp;quot;90210&amp;quot; }
&lt;/pre&gt;

&lt;p&gt;We&amp;rsquo;ll see a large response from this request. This usually goes to the development log file so if we need to debug SOAP calls we can look there to see what the request and response were. The important parts of the response are the request XML and response XML and if we look at the response we&amp;rsquo;ll see that it doesn&amp;rsquo;t contain the information we were expecting.&lt;/p&gt;

&lt;pre class="terminal"&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;
  &amp;lt;soap:Envelope 
    xmlns:soap=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot;
    xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;
    xmlns:xsd=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;
  &amp;lt;soap:Body&amp;gt;
    &amp;lt;GetInfoByZIPResponse xmlns=&amp;quot;http://www.webserviceX.NET&amp;quot; /&amp;gt;
  &amp;lt;/soap:Body&amp;gt;
&amp;lt;/soap:Envelope&amp;gt;
&lt;/pre&gt;

&lt;p&gt;It looks like something&amp;rsquo;s wrong with our request. The problem in this case is that the casr of the us_zip code parameter is incorrect. Parameters are case sensitive and if we look at the relevant part of the request XML we&amp;rsquo;ll see that the USZip parameter was sent as usZip instead.&lt;/p&gt;

&lt;pre class="terminal"&gt;
&amp;lt;web:usZip&amp;gt;90210&amp;lt;/web:usZip&amp;gt;
&lt;/pre&gt;

&lt;p&gt;By default Savon uses lowerCamelCase for parameters, but if we pass the name in as a string instead of as a symbol the capitalization will be preserved.&lt;/p&gt;

&lt;pre class="terminal"&gt;
&amp;gt; client.request :web, :get_info_by_zip, body: { &amp;quot;USZip&amp;quot; =&amp;gt; &amp;quot;90210&amp;quot; }
&lt;/pre&gt; 

&lt;p&gt;When we send the request this time the response contains the information we need.&lt;/p&gt;

&lt;pre class="terminal"&gt;
&amp;lt;soap:Envelope xmlns:soap=&amp;quot;http://schemas.xmlsoap.org/soap/envelope/&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xmlns:xsd=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;&amp;gt;
  &amp;lt;soap:Body&amp;gt;
    &amp;lt;GetInfoByZIPResponse xmlns=&amp;quot;http://www.webserviceX.NET&amp;quot;&amp;gt;
      &amp;lt;GetInfoByZIPResult&amp;gt;
        &amp;lt;NewDataSet xmlns=&amp;quot;&amp;quot;&amp;gt;
          &amp;lt;Table&amp;gt;
            &amp;lt;CITY&amp;gt;Beverly Hills&amp;lt;/CITY&amp;gt;
            &amp;lt;STATE&amp;gt;CA&amp;lt;/STATE&amp;gt;
            &amp;lt;ZIP&amp;gt;90210&amp;lt;/ZIP&amp;gt;
            &amp;lt;AREA_CODE&amp;gt;310&amp;lt;/AREA_CODE&amp;gt;
            &amp;lt;TIME_ZONE&amp;gt;P&amp;lt;/TIME_ZONE&amp;gt;
          &amp;lt;/Table&amp;gt;
        &amp;lt;/NewDataSet&amp;gt;
      &amp;lt;/GetInfoByZIPResult&amp;gt;
    &amp;lt;/GetInfoByZIPResponse&amp;gt;
  &amp;lt;/soap:Body&amp;gt;
&amp;lt;/soap:Envelope&amp;gt;
&lt;/pre&gt;

&lt;p&gt;The last command we sent returns a response object and we can assign this to a variable in the console by using an underscore to get the last thing returned.&lt;/p&gt;

&lt;pre class="terminal"&gt;
&amp;gt; response = _
&lt;/pre&gt;

&lt;p&gt;Calling to_hash on this object gives us a Ruby hash that&amp;rsquo;s easy to parse.&lt;/p&gt;

&lt;pre class="terminal"&gt;
&amp;gt; response.to_hash
 =&amp;gt; {:get_info_by_zip_response=&amp;gt; {:get_info_by_zip_result=&amp;gt; {:new_data_set=&amp;gt;{:table=&amp;gt; {:city=&amp;gt;&amp;quot;Beverly Hills&amp;quot;, :state=&amp;gt;&amp;quot;CA&amp;quot;, :zip=&amp;gt;&amp;quot;90210&amp;quot;, :area_code=&amp;gt;&amp;quot;310&amp;quot;, :time_zone=&amp;gt;&amp;quot;P&amp;quot;}, :@xmlns=&amp;gt;&amp;quot;&amp;quot;}}, :@xmlns=&amp;gt;&amp;quot;http://www.webserviceX.NET&amp;quot;}} 
&lt;/pre&gt;   

&lt;p&gt;The information we need is fairly deeply nested in the hash but we can still get at it fairly easily. Now that we know how Savon works we can start to use it in our Rails application.&lt;/p&gt; 

&lt;h3&gt;Using Savon in a Rails Application&lt;/h3&gt;

&lt;p&gt;Our application has a &lt;code&gt;ZipCode&lt;/code&gt; model class. This isn&amp;rsquo;t an ActiveRecord model just a Ruby class with some attributes and an initializer that takes a Zip code.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/models/zip_code.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
class ZipCode
  attr_reader :state, :city, :area_code, :time_zone

  def initialize(zip)
  end
end
&lt;/pre&gt;

&lt;p&gt;When a new &lt;code&gt;ZipCode&lt;/code&gt; object is instantiated we want to set the attributes with values from the SOAP call. The code we&amp;rsquo;ll need to add to the class is similar to that we ran in the console.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/models/zip_code.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
class ZipCode
  attr_reader :state, :city, :area_code, :time_zone

  def initialize(zip)
    client = Savon::Client.new(&amp;quot;http://www.webservicex.net/uszip.asmx?WSDL&amp;quot;)
    response = client.request :web, :get_info_by_zip, body: { &amp;quot;USZip&amp;quot; =&amp;gt; zip }
    data = data = response.to_hash[:get_info_by_zip_response][:get_info_by_zip_result][:new_data_set][:table]
    @state = data[:state]
    @city = data[:city]
    @area_code = data[:area_code]
    @time_zone = data[:time_zone]
  end
end
&lt;/pre&gt;

&lt;p&gt;This code makes a request and calls &lt;code&gt;to_hash&lt;/code&gt; on the response. We then go into that deeply-nested hash and set the class&amp;rsquo;s attributes to the relevant parts of it. We can try this out now. When we enter a Zip code and click &amp;ldquo;Lookup&amp;rdquo; the SOAP call is made and we&amp;rsquo;ll see the information on the page so our code is working.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/789/original/E290I04.png" width="800" height="388" alt="Our application now fetches results."/&gt;
&lt;/div&gt;

&lt;h3&gt;Handling Errors&lt;/h3&gt;

&lt;p&gt;We&amp;rsquo;ll need to modify out code so that it handles errors. As it stands if we enter an invalid Zip code and try to look it up the application raises an exception as the response doesn&amp;rsquo;t have the deeply-nested hash we&amp;rsquo;re expecting.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/801/original/E290I05.png" width="800" height="388" alt="Invalid Zip codes aren&amp;rsquo;t handled correctly."/&gt;
&lt;/div&gt; 

&lt;p&gt;One way to handle these cases is to check that the response is successful before trying to set the attributes. We could use &lt;code&gt;response.success?&lt;/code&gt; to check this and while this is useful, it won&amp;rsquo;t help in this case as the response is successful when an invalid Zip code is entered, the problem is that the response is empty.&lt;/p&gt;

&lt;p&gt;To help us here we can use Savon&amp;rsquo;s &lt;code&gt;to_array&lt;/code&gt; method here instead of &lt;code&gt;to_hash&lt;/code&gt;. We can pass this a list of hash keys and rather than throwing an exception if the nesting we&amp;rsquo;re looking for doesn&amp;rsquo;t exist it will return an empty array. As an array is returned we need to call &lt;code&gt;first&lt;/code&gt; to get the results we want. If there are no results we&amp;rsquo;ll get &lt;code&gt;nil&lt;/code&gt; so we can check for that before setting the attributes.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/models/zip_code.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;
def initialize(zip)
  client = Savon::Client.new(&amp;quot;http://www.webservicex.net/uszip.asmx?WSDL&amp;quot;)
  response = client.request :web, :get_info_by_zip, body: { &amp;quot;USZip&amp;quot; =&amp;gt; zip }
  if response.success?
    data = response.to_array(:get_info_by_zip_response, :get_info_by_zip_result, :new_data_set, :table).first
    if data
      @state = data[:state]
      @city = data[:city]
      @area_code = data[:area_code]
      @time_zone = data[:time_zone]
    end
  end
end
&lt;/pre&gt;

&lt;p&gt;If we reload the page now we&amp;rsquo;ll see an empty result rather than an exception.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="http://asciicasts.com/system/photos/802/original/E290I06.png" width="800" height="388" alt="Invalid Zip codes no longer throw an exception."/&gt;
&lt;/div&gt;

&lt;p&gt;There&amp;rsquo;s more work we can do here to show an error message when an invalid Zip code is entered but we won&amp;rsquo;t do that here.&lt;/p&gt;

&lt;h3&gt;Some Final Tips&lt;/h3&gt;

We&amp;rsquo;ll finish this episode with a couple of tips. If you find yourself having to use strings a lot because the first part of a tag name is capitalized you can add this line of code to our application to make the tags use UpperCamelCase rather than the default lowerCamelCase. If the API you&amp;rsquo;re talking to uses this kind of casing this means that you can use symbols instead of strings in the arguments.

&lt;pre class="ruby"&gt;
Gyoku.convert_symbols_to :camelcase
&lt;/pre&gt;

&lt;p&gt;A WSDL file shouldn&amp;rsquo;t change often so so it&amp;rsquo;s a good idea to cache it rather than downloading it every time. We can download the WSDL file, store it locally and then use a file reference when we create a new &lt;code&gt;Savon::Client&lt;/code&gt; rather than a web reference.&lt;/p&gt; 

&lt;p&gt;That&amp;rsquo;s it for our episode on Savon. Savon makes it much easier to communicate with a SOAP API. If you use it in your applications there are a couple of related projects that you might find useful. The first of these is &lt;a href="https://github.com/rubiii/savon_model"&gt;Savon Model&lt;/a&gt;. This provides a nice DSL for setting up the client inside a class and it would probably work well inside our &lt;code&gt;ZipCode&lt;/code&gt; class and allow us to clean up the code there.&lt;/p&gt;

&lt;p&gt;The other project is &lt;a href="https://github.com/rubiii/savon_spec"&gt;Savon Spec&lt;/a&gt;. This can help in testing by mocking the SOAP requests. This is fine for lower-level tests but to test thoroughly you should also have some higher level integration tests that test hitting that actual API. This way if the API changes the tests will break. The &lt;a href="https://github.com/myronmarston/vcr"&gt;VCR gem&lt;/a&gt; can help greatly with this and there&amp;rsquo;s more information about VCR in this week&amp;rsquo;s pro episode.&lt;/p&gt;</description>
      <pubDate>Sun, 30 Oct 2011 10:33:51 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/290-soap-with-savon</guid>
      <link>http://asciicasts.com/episodes/290-soap-with-savon</link>
    </item>
    <item>
      <title>Billing With Stripe</title>
      <description>&lt;p&gt;If you ever need to process credit card payments through your Rails applications you should take a look at &lt;a href="https://stripe.com"&gt;Stripe&lt;/a&gt;. Stripe is a payment gateway that is easy to set up and which is very developer friendly. It only charges fees on a per-transaction basis and these are very reasonable. There are no monthly fees or other hidden costs. (By the way we&amp;rsquo;re not being paid to say this).&lt;/p&gt;

&lt;p&gt;Stripe is currently only available in the United States so you&amp;rsquo;ll need an account at a U.S. bank if you want to use it in your applications. International support is being worked on, however, and should be available soon. This doesn&amp;rsquo;t mean that you can&amp;rsquo;t bill international customers, the only restriction is that the seller must be in the U.S.&lt;/p&gt; 

&lt;h3&gt;Adding Stripe to a Rails Application&lt;/h3&gt;

&lt;p&gt;In this episode we&amp;rsquo;ll use Stripe to add recurring payments to a Rails application. The application we&amp;rsquo;ll use is a site that sells Llama Kisses. Why? Well Ryan Bates grew up on a llama ranch and missed out on the opportunity to sell llama kisses then so he&amp;rsquo;s making up for lost time now.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/760/original/E288I01.png" width="821" height="518" alt="The Llama Kisses site."/&gt;
&lt;/div&gt;

&lt;p&gt;Most of the application is already written. There are four different plans and users can sign up for any one of them to create a subscription. There&amp;rsquo;s only an email field on the sign-up page right now and when we fill that field in and submit the form a new subscription will be created. So that we can take payments through Stripe we&amp;rsquo;ll add some more fields for credit card details.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/761/original/E288I02.png" width="821" height="332" alt="The signup form."/&gt;
&lt;/div&gt;

&lt;p&gt;Getting started with Stripe is easy. It we visit &lt;a href="https://stripe.com/"&gt;stripe.com&lt;/a&gt; and click the &amp;ldquo;Get Started with Stripe&amp;rdquo; button we&amp;rsquo;ll be taken to a page where we can process test transactions. We can also do this from the command line with curl. If we copy the example code from the &lt;a href="https://manage.stripe.com"&gt;&amp;ldquo;Getting Started&amp;rdquo; page&lt;/a&gt; and run it in a terminal window we should see some JSON returned.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ curl https://api.stripe.com/v1/charges \
&amp;gt;   -u zVyGPfdmfhSGpHAxhFiJT7kFnHeSi9ZN: \
&amp;gt;   -d amount=100 \
&amp;gt;   -d currency=usd \
&amp;gt;   -d &amp;#x27;card[number]=4242424242424242&amp;#x27; \
&amp;gt;   -d &amp;#x27;card[exp_month]=5&amp;#x27; \
&amp;gt;   -d &amp;#x27;card[exp_year]=2012&amp;#x27; \
&amp;gt;   -d &amp;#x27;description=test charge IFnFXZgdZk&amp;#x27;

{
  &amp;quot;amount&amp;quot;: 100,
  &amp;quot;created&amp;quot;: 1318355241,
  &amp;quot;currency&amp;quot;: &amp;quot;usd&amp;quot;,
  &amp;quot;description&amp;quot;: &amp;quot;test charge IFnFXZgdZk&amp;quot;,
  &amp;quot;fee&amp;quot;: 0,
  &amp;quot;id&amp;quot;: &amp;quot;ch_oVfzHImv8sN5TV&amp;quot;,
  &amp;quot;livemode&amp;quot;: false,
  &amp;quot;object&amp;quot;: &amp;quot;charge&amp;quot;,
  &amp;quot;paid&amp;quot;: true,
  &amp;quot;refunded&amp;quot;: false,
  &amp;quot;card&amp;quot;: {
    &amp;quot;country&amp;quot;: &amp;quot;US&amp;quot;,
    &amp;quot;exp_month&amp;quot;: 5,
    &amp;quot;exp_year&amp;quot;: 2012,
    &amp;quot;last4&amp;quot;: &amp;quot;4242&amp;quot;,
    &amp;quot;object&amp;quot;: &amp;quot;card&amp;quot;,
    &amp;quot;type&amp;quot;: &amp;quot;Visa&amp;quot;
  }
}&lt;/pre&gt;

&lt;p&gt;Whether we run a test transaction through the site or through the terminal window the recent payments are shown in the dashboard at the bottom of Stripe&amp;rsquo;s management page.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/762/original/E288I03.png" width="822" height="586" alt="Stripe&amp;rsquo;s dashboard showing our test payments."/&gt;
&lt;/div&gt;

&lt;p&gt;Creating an account is easy; all we need to is enter an email address and a password on the management page. Once we&amp;rsquo;ve done that we can visit &lt;a href="https://manage.stripe.com/account"&gt;the page for our account&lt;/a&gt; where we&amp;rsquo;ll see, amongst other things, the API keys we&amp;rsquo;ll need to communicate with Stripe&amp;rsquo;s REST API. Stripe also provide a Ruby gem that makes using this API in Rails applications much easier. We&amp;rsquo;ll install this gem in our application now. As with most Ruby gems we do this by adding a reference to it the &lt;code&gt;Gemfile&lt;/code&gt; and then 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;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;stripe&amp;#x27;&lt;/pre&gt;

&lt;p&gt;Stripe needs two API keys so that it knows which account it&amp;rsquo;s working with. We&amp;rsquo;ll store these in a new &lt;code&gt;stripe.rb&lt;/code&gt; initializer file in the application&amp;rsquo;s &lt;code&gt;/config/initializers&lt;/code&gt; directory. The keys we need to store here are the secret test key that&amp;rsquo;s shown in our account page and the public API key here. We&amp;rsquo;ll store the public key in a constant as it isn&amp;rsquo;t used by the Ruby gem, only in views and JavaScript. This key should hold the value from the publishable test key on our Stripe account page.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/config/initializers/stripe.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;Stripe.api_key = &amp;quot;5J7dr36JmNpLrXXFwAXChdRzZZwLyCHV&amp;quot;
STRIPE_PUBLIC_KEY = &amp;quot;pk_B1SaM15nXXruDU3g2D6uns2kJeu9m&amp;quot;&lt;/pre&gt;

&lt;p&gt;As this file contains sensitive information it&amp;rsquo;s a good idea to add it to the application&amp;rsquo;s &lt;code&gt;.gitignore&lt;/code&gt; file so that it isn&amp;rsquo;t included in the repository. Also, as we&amp;rsquo;ll use different keys on the production site we don&amp;rsquo;t want this file being accidentally copied over to the production codebase.&lt;/p&gt; 

&lt;h3&gt;Adding Stripe&amp;rsquo;s JavaScript and The API Key&lt;/h3&gt;

&lt;p&gt;When a user submits their credit card information in a form the credit card information goes directly to Stripe&amp;rsquo;s server and not to our application at all. This makes it a lot easier to get &lt;a href="http://en.wikipedia.org/wiki/Payment_Card_Industry_Data_Security_Standard"&gt;PCI compliance&lt;/a&gt;. If we look at the example form on &lt;a href="https://stripe.com/api"&gt;Stripe&amp;rsquo;s API page&lt;/a&gt; we&amp;rsquo;ll see that none of its fields have a &lt;code&gt;name&lt;/code&gt; attribute. This means that when the form is submitted these fields aren&amp;rsquo;t passed to our application&amp;rsquo;s server. Instead they&amp;rsquo;ll read by some JavaScript code that is triggered when a user submits the form.&lt;/p&gt;

&lt;p&gt;To use Stripe in our application we need to include a JavaScript file from Stripe&amp;rsquo;s server. Then we set our publishable key and add some JavaScript that will fire when the form containing the credit card fields is submitted. This JavaScript will generate a token based on the credit card information from the form.&lt;/p&gt;

&lt;p&gt;We&amp;rsquo;ll add Stripe&amp;rsquo;s JavaScript file in our application&amp;rsquo;s layout file. It needs to be placed before the application&amp;rsquo;s own JavaScript file. We could add some code that checks if the current page is the checkout page and only adds the script when this is the case, but we won&#8217;t do that here. We also need to make our public key available to JavaScript and we&amp;rsquo;ll do this the same way that Rails adds its CSRF key, in a &lt;code&gt;meta&lt;/code&gt; tag in the head of the page.&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;Llama Kisses&amp;lt;/title&amp;gt;
  &amp;lt;%= stylesheet_link_tag    &amp;quot;application&amp;quot; %&amp;gt;
  &amp;lt;%= javascript_include_tag &amp;quot;https://js.stripe.com/v1/&amp;quot;, &amp;quot;application&amp;quot; %&amp;gt;
  &amp;lt;%= csrf_meta_tags %&amp;gt;
  &amp;lt;%= tag :meta, :name =&amp;gt; &amp;quot;stripe-key&amp;quot;, &amp;crarr; 
    :content =&amp;gt; STRIPE_PUBLIC_KEY %&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;h3&gt;Adding Credit Card Fields To The Subscription Form&lt;/h3&gt;

&lt;p&gt;Next we&amp;rsquo;ll add the credit card fields to the subscription form. The form currently contains a hidden field that holds the &lt;code&gt;id&lt;/code&gt; of the selected plan and a text field for an email address. We&amp;rsquo;ll add more fields for a credit card number, security code and expiration date.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/subscriptions/new.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;%= form_for @subscription do |f| %&amp;gt;
  &amp;lt;% if @subscription.errors.any? %&amp;gt;
    &amp;lt;div class=&amp;quot;error_messages&amp;quot;&amp;gt;
      &amp;lt;h2&amp;gt;&amp;lt;%= pluralize(@subscription.errors.count, &amp;quot;error&amp;quot;) %&amp;gt; prohibited this subscription from being saved:&amp;lt;/h2&amp;gt;
      &amp;lt;ul&amp;gt;
      &amp;lt;% @subscription.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;%= f.hidden_field :plan_id %&amp;gt;
  &amp;lt;div class=&amp;quot;field&amp;quot;&amp;gt;
    &amp;lt;%= f.label :email %&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;%= label_tag :card_number, &amp;quot;Credit Card Number &amp;quot; %&amp;gt;
      &amp;lt;%= text_field_tag :card_number, nil, name: nil %&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;field&amp;quot;&amp;gt;
      &amp;lt;%= label_tag :card_code, &amp;quot;Security Code on Card (CVV)&amp;quot; %&amp;gt;
      &amp;lt;%= text_field_tag :card_code, nil, name: nil %&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;field&amp;quot;&amp;gt;
    &amp;lt;%= label_tag :card_month, &amp;quot;Card Expiration&amp;quot; %&amp;gt;
    &amp;lt;%= select_month nil, {add_month_numbers_true: true}, {name: nil, id: &amp;quot;card_month&amp;quot;}%&amp;gt;
    &amp;lt;%= select_year nil, {start_year: Date.today.year, end_year: Date.today.year+15}, {name: nil, id: &amp;quot;card_year&amp;quot;}%&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;actions&amp;quot;&amp;gt;&amp;lt;%= f.submit &amp;quot;Subscribe&amp;quot; %&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;% end %&amp;gt;&lt;/pre&gt;

&lt;p&gt;We&amp;rsquo;ve added two text fields to the form, one for a credit card number, and one for the security code and also two dropdowns for the expiry date. There are a few things worth noting about the fields we&amp;rsquo;ve added. For the credit card name and security code we&amp;rsquo;ve used &lt;code&gt;label_tag&lt;/code&gt; and &lt;code&gt;text_field_tag&lt;/code&gt; instead of going through the form builder as these new fields aren&amp;rsquo;t attributes on our &lt;code&gt;Subscription&lt;/code&gt; model. We don&amp;rsquo;t want them to be submitted back to the server at all so we&amp;rsquo;ve also specified a &lt;code&gt;nil&lt;/code&gt; name for each field. Similarly for the expiry date fields we&amp;rsquo;re using &lt;code&gt;select_month&lt;/code&gt; and &lt;code&gt;select_year&lt;/code&gt; for the expiry date and specifying the &lt;code&gt;id&lt;/code&gt; manually so that we don&amp;rsquo;t have to deal with the one that Rails generates.&lt;/p&gt;

&lt;p&gt;When we reload the page the new fields are shown in the form.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/763/original/E288I04.png" width="822" height="505" alt="The subscription form with its new credit card fields."/&gt;
&lt;/div&gt;

&lt;p&gt;Next we want to write the JavaScript that fires when the form is submitted. This script will submit the credit card information to Stripe and submit the token that it receives back from Stripe through the form. As our application is written in Rails 3.1 we&amp;rsquo;ll write this code in CoffeeScript in the &lt;code&gt;subscriptions.js.coffee&lt;/code&gt; file.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/javascripts/subscriptions.js.coffee&lt;/p&gt;
&lt;pre class="javascript"&gt;jQuery -&amp;gt;
  Stripe.setPublishableKey($(&amp;#x27;meta[name=&amp;quot;stripe-key&amp;quot;]&amp;#x27;).attr(&amp;#x27;content&amp;#x27;))
  subscription.setupForm()

subscription =
  setupForm: -&amp;gt;
    $(&amp;#x27;#new_subscription&amp;#x27;).submit -&amp;gt;
      $(&amp;#x27;input[type=submit]&amp;#x27;).attr(&amp;#x27;disabled&amp;#x27;, true)
      subscription.processCard()
  
  processCard: -&amp;gt;
    card =
      number: $(&amp;#x27;#card_number&amp;#x27;).val()
      cvc: $(&amp;#x27;#card_code&amp;#x27;).val()
      expMonth: $(&amp;#x27;#card_month&amp;#x27;).val()
      expYear: $(&amp;#x27;#card_year&amp;#x27;).val()
    Stripe.createToken(card, subscription.handleStripeResponse)
  
  handleStripeResponse: (status, response) -&amp;gt;
    if status == 200
      alert(response.id)
    else
	 alert(response.error.message)&lt;/pre&gt; 
	 
&lt;p&gt;This code should only run after the page&amp;rsquo;s DOM has loaded and so it&amp;rsquo;s all wrapped in the &lt;code&gt;jQuery&lt;/code&gt; function. The first thing it does is set up Stripe by specifying the publishable key. The key&amp;rsquo;s value is read from the &lt;code&gt;meta&lt;/code&gt; tag we added in the application&amp;rsquo;s layout file. We fetch it by looking for a &lt;code&gt;meta&lt;/code&gt; tag with a &lt;code&gt;name&lt;/code&gt; attribute that has a value of &lt;code&gt;stripe&lt;/code&gt; and reading that tag&amp;rsquo;s &lt;code&gt;content&lt;/code&gt; attribute. The rest of the logic is handled through a &lt;code&gt;subscription&lt;/code&gt; object. This object has a function called &lt;code&gt;setupForm&lt;/code&gt; that will do all of the work.&lt;/p&gt;

&lt;p&gt;Next we create the &lt;code&gt;subscription&lt;/code&gt; object and give it a &lt;code&gt;setupForm&lt;/code&gt; function. In this function we get the subscription form by its &lt;code&gt;id&lt;/code&gt; and add a callback that fires when the form&amp;rsquo;s &lt;code&gt;submit&lt;/code&gt; event fires.  When the form is submitted we disable the submit button to stop the it from being accidentally submitted again by setting the button&amp;rsquo;s disabled attribute to &lt;code&gt;true&lt;/code&gt;. Then we call a &lt;code&gt;processCard&lt;/code&gt; function and return &lt;code&gt;false&lt;/code&gt; so that the form isn&amp;rsquo;t submitted.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;processCard&lt;/code&gt; function creates an object representing the credit card&amp;rsquo;s values in the format that Stripe expects and reads the appropriate values for each field from the form&amp;rsquo;s fields using &lt;code&gt;val()&lt;/code&gt;. The next line is the important one. We call &lt;code&gt;Stripe.createToken&lt;/code&gt; with two arguments. The first is the card object that we&amp;rsquo;ve just created (we can also pass in an optional amount here). The second is a function that will handle the response from Stripe, which happens asynchronously. We&amp;rsquo;ll pass in &lt;code&gt;subscription.handleStripeResponse&lt;/code&gt; here.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;handleStripeResponse&lt;/code&gt; function takes two arguments: a &lt;code&gt;status&lt;/code&gt; and a &lt;code&gt;response&lt;/code&gt;. If the status has a value of &lt;code&gt;200&lt;/code&gt; then the transaction succeeded and we&amp;rsquo;ll have a response token stored in &lt;code&gt;response.id&lt;/code&gt;. For now we&amp;rsquo;ll just &lt;code&gt;alert&lt;/code&gt; the response value so that we can see what it is. If the status isn&amp;rsquo;t &lt;code&gt;200&lt;/code&gt; then an error has occurred so we&amp;rsquo;ll &lt;code&gt;alert&lt;/code&gt; the error message.&lt;/p&gt;

&lt;p&gt;We can give our new form a try out now. If we reload the new subscription form and submit valid card details we get a response token back.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/764/original/E288I05.png" width="827" height="506" alt="The response token shown for a valid request."/&gt;
&lt;/div&gt;

&lt;p&gt;If we enter an invalid card number we&amp;rsquo;ll get an error message returned instead.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/765/original/E288I06.png" width="822" height="505" alt="An error message is returned if we enter invalid details."/&gt;
&lt;/div&gt;

&lt;h3&gt;Handling The Response&lt;/h3&gt;

&lt;p&gt;Now that we know that the calls to Stripe are being processed correctly we&amp;rsquo;ll improve the code that handles the error messages. Instead of showing an alert we&amp;rsquo;ll show the error message on the page in a div with and id of stripe_error and re-enable the submit button so that the user can enter their details again.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/javascripts/subscriptions.js.coffee&lt;/p&gt;
&lt;pre class="javascript"&gt;handleStripeResponse: (status, response) -&amp;gt;
  if status == 200
    alert(response.id)
  else
    $(&amp;#x27;#stripe_error&amp;#x27;).text(response.error.message)
    $(&amp;#x27;input[type=submit]&amp;#x27;).attr(&amp;#x27;disabled&amp;#x27;, false)&lt;/pre&gt;
    
&lt;p&gt;Having done this we&amp;rsquo;ll need to add the &lt;code&gt;div&lt;/code&gt; to the view.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/subscriptions/new.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;%= form_for @subscription do |f| %&amp;gt;
  &amp;lt;!-- Form fields omitted --&amp;gt;
  &amp;lt;div id=&amp;quot;stripe_error&amp;quot;&amp;gt;
    &amp;lt;noscript&amp;gt;JavaScript is not enabled and is required for this form. First enable it in your web browser settings.&amp;lt;/noscript&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;actions&amp;quot;&amp;gt;&amp;lt;%= f.submit &amp;quot;Subscribe&amp;quot; %&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;% end %&amp;gt;&lt;/pre&gt;

&lt;p&gt;We&amp;rsquo;ve placed a &lt;code&gt;noscript&lt;/code&gt; element in the &lt;code&gt;div&lt;/code&gt; so that an error is shown if anyone tries to use the form in a browser that doesn&amp;rsquo;t have JavaScript enabled. When we reload the page and submit the form with an invalid credit card number again we&amp;rsquo;ll see the error message in the &lt;code&gt;stripe_error&lt;/code&gt; div instead of an &lt;code&gt;alert&lt;/code&gt;.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/766/original/E288I07.png" width="822" height="534" alt="The error message is now shown on the page."/&gt;
&lt;/div&gt;

&lt;p&gt;Next we&amp;rsquo;ll change the code that handles successful transactions. Instead of displaying the response token in an &lt;code&gt;alert&lt;/code&gt; we&amp;rsquo;ll add it to a new hidden field in the form and then submit the form. We&amp;rsquo;ll add a new hidden field in the view and call it &lt;code&gt;stripe_card_token&lt;/code&gt;.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/subscriptions/new.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;%= f.hidden_field :stripe_card_token %&amp;gt;&lt;/pre&gt;

&lt;p&gt;There&amp;rsquo;s no &lt;code&gt;stripe_card_token&lt;/code&gt; field in the &lt;code&gt;subscriptions&lt;/code&gt; table in the database so we&amp;rsquo;ll need to add this field as a virtual attribute in our &lt;code&gt;Subscription&lt;/code&gt; model.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/models/subscription.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;class Subscription &amp;lt; ActiveRecord::Base
  belongs_to :plan
  validates_presence_of :plan_id
  validates_presence_of :email
  
  attr_accessible :stripe_card_token
end&lt;/pre&gt;

&lt;p&gt;Back in our CoffeeScript file we&amp;rsquo;ll replace the &lt;code&gt;alert&lt;/code&gt; with code that sets the value of our new hidden field to the value of the response token and then submits the form. We submit the form by calling &lt;code&gt;submit&lt;/code&gt; directly on the form. Doing this bypasses the &lt;code&gt;onsubmit&lt;/code&gt; callback so that the form is POSTed back to the server.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/javascripts/subscriptions.js.coffee&lt;/p&gt;
&lt;pre class="ruby"&gt;handleStripeResponse: (status, response) -&amp;gt;
  if status == 200
    $(&amp;#x27;#subscription_stripe_card_token&amp;#x27;).val(response.id)
    $(&amp;#x27;#new_subscription&amp;#x27;)[0].submit()
  else
    $(&amp;#x27;#stripe_error&amp;#x27;).text(response.error.message)
    $(&amp;#x27;input[type=submit]&amp;#x27;).attr(&amp;#x27;disabled&amp;#x27;, false)&lt;/pre&gt;
    
&lt;p&gt;The form is submitted to the &lt;code&gt;SubscriptionsController&lt;/code&gt;&amp;rsquo;s &lt;code&gt;create&lt;/code&gt; action and the token will be passed in to a new &lt;code&gt;Subscription&lt;/code&gt;. We could handle the payment through a &lt;code&gt;before_create&lt;/code&gt; callback here but instead we&amp;rsquo;ll create a new method in the &lt;code&gt;Subscription&lt;/code&gt; model called &lt;code&gt;save_with_payment&lt;/code&gt; and do it there. Before we write this method we&amp;rsquo;ll replace the call to &lt;code&gt;save&lt;/code&gt; with &lt;code&gt;save_with_payment&lt;/code&gt;.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/controllers/subscription_controller.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;def create
  @subscription = Subscription.new(params[:subscription])
  if @subscription.save_with_payment
    redirect_to @subscription, :notice =&amp;gt; &amp;quot;Thank you for &amp;crarr; 
      subscribing!&amp;quot;
  else
    render :new
  end
end&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;save_with_payment&lt;/code&gt; method will use the &lt;code&gt;stripe&lt;/code&gt; gem to handle the payment. We could use the response token to make a payment using the &lt;code&gt;Stripe::Charge.create&lt;/code&gt; method but we don&amp;rsquo;t want to do this as the response token can only be used once and we want to make a recurring payment. Instead we&amp;rsquo;ll use the token to create a new &lt;code&gt;Stripe::Customer&lt;/code&gt;. We can then assign a plan to that customer with recurring payments. Stripe will then automatically handle recurring payments for us. All of this is covered in Stripe&amp;rsquo;s excellent &lt;a href="https://stripe.com/docs/api?lang=ruby"&gt;API documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Before we make any changes to our &lt;code&gt;Subscription&lt;/code&gt; model we&amp;rsquo;ll go to our Stripe account and set up some plans so that it knows how to handle our recurring payments. We&amp;rsquo;ll add four plans with names and ids that match the plans in our Rails application.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/767/original/E288I08.png" width="799" height="528" alt="The plans added to our Stripe account."/&gt;
&lt;/div&gt;

&lt;p&gt;Back in our &lt;code&gt;Subscription&lt;/code&gt; model we can now write the &lt;code&gt;save_with_payment&lt;/code&gt; method.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/models/subscription.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;class Subscription &amp;lt; ActiveRecord::Base
  belongs_to :plan
  validates_presence_of :plan_id
  validates_presence_of :email
  
  attr_accessor :stripe_card_token
  
  def save_with_payment
    if valid?
      customer = Stripe::Customer.create(description:email, &amp;crarr; 
        plan: plan_id, card: stripe_card_token)
      self.stripe_customer_token = customer.id
      save!
    end
  end
end&lt;/pre&gt;

&lt;p&gt;This method checks that the model is valid and if it is it will create a new &lt;code&gt;Stripe::Customer&lt;/code&gt;, passing it the customer&amp;rsquo;s email address as a description, the &lt;code&gt;plan_id&lt;/code&gt; and the &lt;code&gt;stripe_card_token&lt;/code&gt;. Stripe will create a new &lt;code&gt;id&lt;/code&gt; for the customer which we&amp;rsquo;ll need to save to the database. We&amp;rsquo;ll save it in to a new  &lt;code&gt;stripe_customer_token&lt;/code&gt; field. We&amp;rsquo;ll create a migration for this field then run &lt;code&gt;rake db:migrate&lt;/code&gt; to add it to the database.&lt;/p&gt;

&lt;pre class="terminal"&gt;$ rails g migration add_stripe_to_subscriptions stripe_customer_token:string&lt;/pre&gt;
    
&lt;p&gt;We&amp;rsquo;re ready now to test making a payment. If we go to the new subscription page, enter valid credit card details and click &amp;ldquo;Subscribe&amp;rdquo; the token and customer will be created in the background and the form will be submitted. If we visit the payments page for our Stripe account we&amp;rsquo;ll see the new payment listed for the price of the plan. This is a recurring payment and will be taken every month.&lt;/p&gt; 

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/768/original/E288I09.png" width="818" height="557" alt="The recurring payment shown in the dashboard."/&gt;
&lt;/div&gt;

&lt;h3&gt;Handling Errors&lt;/h3&gt;

&lt;p&gt;The call to &lt;code&gt;Stripe::Customer.create&lt;/code&gt; might raise an exception if some of the information passed isn&amp;rsquo;t valid. This can happen, for example, if a user submits the form without JavaScript enabled in their browser so that the &lt;code&gt;stripe_card_token&lt;/code&gt; wasn&amp;rsquo;t generated. It&amp;rsquo;s a good idea to use rescue to handle these cases. Stripe will raise an &lt;code&gt;InvalidRequestError&lt;/code&gt; in these cases and we can catch these, log them, add a validation error to the page and then show the form again.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/models/subscription.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;def save_with_payment
  if valid?
    customer = Stripe::Customer.create(description:email, &amp;crarr;
      plan: plan_id, card: stripe_card_token)
    self.stripe_customer_token = customer.id
    save!
  end
rescue Stripe::InvalidRequestError =&amp;gt; e
  logger.error &amp;quot;Stripe error while creating customer: #{e.mesage}&amp;quot;
  errors.add :base, &amp;quot;There was a problem with your credit card.&amp;quot;
end&lt;/pre&gt;

&lt;p&gt;We also need to handle errors on form fields unrelated to credit card information, such as the email field on our form, better. Currently if we try to submit a subscription with no email address but with valid credit card details we&amp;rsquo;ll receive a proper token from Stripe but instead of being redirected to the page that shows a successful login we&amp;rsquo;ll be shown the form again with an email validation error.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/769/original/E288I10.png" width="799" height="600" alt="The credit card fields still show even after we&amp;rsquo;ve entered valid information."/&gt;
&lt;/div&gt;

&lt;p&gt;In these cases we should hide the credit card fields as we already have a valid token. We can do this by modifying the view so that it hides the fields if a &lt;code&gt;stripe_card_token&lt;/code&gt; exists for the subscription and shows a message instead.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/subscriptions/new.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;div class=&amp;quot;field&amp;quot;&amp;gt;
  &amp;lt;%= f.label :email %&amp;gt;
  &amp;lt;%= f.text_field :email %&amp;gt;
&amp;lt;/div&amp;gt;  
&amp;lt;% if @subscription.stripe_card_token %&amp;gt;
  Credit card has been provided
&amp;lt;% else %&amp;gt;
  &amp;lt;div class=&amp;quot;field&amp;quot;&amp;gt;
    &amp;lt;%= label_tag :card_number, &amp;quot;Credit Card Number &amp;quot; %&amp;gt;
    &amp;lt;%= text_field_tag :card_number, nil, name: nil %&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;field&amp;quot;&amp;gt;
    &amp;lt;%= label_tag :card_code, &amp;quot;Security Code on Card (CVV)&amp;quot; %&amp;gt;
    &amp;lt;%= text_field_tag :card_code, nil, name: nil %&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;field&amp;quot;&amp;gt;
    &amp;lt;%= label_tag :card_month, &amp;quot;Card Expiration&amp;quot; %&amp;gt;
    &amp;lt;%= select_month nil, {add_month_numbers_true: true}, &amp;crarr; 
      {name: nil, id: &amp;quot;card_month&amp;quot;}%&amp;gt;
    &amp;lt;%= select_year nil, {start_year: Date.today.year, &amp;crarr;
      end_year: Date.today.year+15}, &amp;crarr;
      {name: nil, id: &amp;quot;card_year&amp;quot;} %&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;% end %&amp;gt;&lt;/pre&gt;

&lt;p&gt;We&amp;rsquo;ll also need to update the &lt;code&gt;setupForm&lt;/code&gt; function in our subscriptions CoffeeScript file so that it doesn&amp;rsquo;t try to process the card again when a user submits the form in this case. We can do this by checking to see if the card number field exists on the form. If it doesn&amp;rsquo;t then it&amp;rsquo;s been hidden because the credit card information has already been processed. In this case we won&amp;rsquo;t process it again and we&amp;rsquo;ll return &lt;code&gt;true&lt;/code&gt; so that the form is submitted.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/assets/javascripts/subscriptions.js.coffee&lt;/p&gt;
&lt;pre class="javascript"&gt;setupForm: -&amp;gt;
  $(&amp;#x27;#new_subscription&amp;#x27;).submit -&amp;gt;
    $(&amp;#x27;input[type=submit]&amp;#x27;).attr(&amp;#x27;disabled&amp;#x27;, true)
    if $(&amp;#x27;#card_number&amp;#x27;).length
      subscription.processCard()
      false
    else
      true&lt;/pre&gt;
      
&lt;p&gt;If we submit the form with valid credit card details but with a missing email address now the credit card fields will be hidden.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/770/original/E288I11.png" width="799" height="466" alt="The credit card fields are now hidden."/&gt;
&lt;/div&gt;

&lt;p&gt;If we fill in the email field and submit the form again our subscription will be successful and the payment will be processed by Stripe.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/771/original/E288I12.png" width="799" height="321" alt="When we enter a valid email address our subscription is successfully submitted."/&gt;
&lt;/div&gt;

&lt;h3&gt;WebHooks&lt;/h3&gt;

&lt;p&gt;One feature of Stripe that we haven&amp;rsquo;t covered is WebHooks. These allow us to provide a callback URL that Stripe will call when a given event fires. For example if a recurring payment fails we want to be told about this so that we can suspend that user&amp;rsquo;s account. We can then inform them so that they can update their credit card information. Speaking of which, our application still needs a way for users to update their card information, cancel their subscriptions and so on, but we won&amp;rsquo;t be covering that here.&lt;/p&gt;

&lt;p&gt;Stripe has a number of features we haven&amp;rsquo;t covered in this episode, but hopefully we&amp;rsquo;ve given you enough to get started. Stripe is a great way to process credit card payments. Unfortunately it&amp;rsquo;s unavailable outside the U.S. for now, but international support is promised soon.&lt;/p&gt;</description>
      <pubDate>Fri, 14 Oct 2011 12:59:53 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/288-billing-with-stripe</guid>
      <link>http://asciicasts.com/episodes/288-billing-with-stripe</link>
    </item>
    <item>
      <title>Draper</title>
      <description>&lt;p&gt;In this episode we&amp;rsquo;ll take a look a &lt;a href="https://github.com/jcasimir/draper"&gt;Draper&lt;/a&gt;, a gem that lets us add decorators to a Rails application&amp;rsquo;s views much like a presenter pattern. If you find that you have a lot of complex view logic in your templates and helper methods Draper can help to clean up this code by taking a more object-orientated approach. We&amp;rsquo;ll show you how it works in this episode.&lt;/p&gt;

&lt;p&gt;The application we&amp;rsquo;ll be working with is shown below. It has a user profile page that shows various pieces of information about a given user including their avatar, full name, username, a short biography in Markdown and links to a website and Twitter feed. If a user has supplied a website the avatar and full name will link to that site.&lt;/p&gt; 

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/747/original/E286I01.png" width="800" height="595" alt="The profile page for a user who has entered all of their details."/&gt;
&lt;/div&gt;

&lt;p&gt;The page seems fairly simple but we also have to handle those users who haven&amp;rsquo;t entered so much data such as &amp;ldquo;MrMystery&amp;rdquo;.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/748/original/E286I02.png" width="800" height="470" alt="The profile page for a user who has entered few details."/&gt;
&lt;/div&gt;

&lt;p&gt;This user has only entered a username so we display that in place of their full name, show a default avatar and some placeholder text for the other fields. This makes the template for this page more complex, with many if conditions needed to handle users with different amounts of information. We could make this template much cleaner if we could move some of this logic out to somewhere else.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/users/show.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;div id=&amp;quot;profile&amp;quot;&amp;gt;
  &amp;lt;%= link_to_if @user.url.present?, &amp;crarr; 
  image_tag(&amp;quot;avatars/#{avatar_name(@user)}&amp;quot;, class: &amp;quot;avatar&amp;quot;), &amp;crarr;
  @user.url %&amp;gt;
  &amp;lt;h1&amp;gt;&amp;lt;%= link_to_if @user.url.present?, &amp;crarr;
    (@user.full_name.present? ? @user.full_name : &amp;crarr;
    @user.username), @user.url %&amp;gt;&amp;lt;/h1&amp;gt;
  &amp;lt;dl&amp;gt;
    &amp;lt;dt&amp;gt;Username:&amp;lt;/dt&amp;gt;
    &amp;lt;dd&amp;gt;&amp;lt;%= @user.username %&amp;gt;&amp;lt;/dd&amp;gt;
    &amp;lt;dt&amp;gt;Member Since:&amp;lt;/dt&amp;gt;
    &amp;lt;dd&amp;gt;&amp;lt;%= @user.member_since %&amp;gt;&amp;lt;/dd&amp;gt;
    &amp;lt;dt&amp;gt;Website:&amp;lt;/dt&amp;gt;
    &amp;lt;dd&amp;gt;
    &amp;lt;% if @user.url.present? %&amp;gt;
      &amp;lt;%= link_to @user.url, @user.url %&amp;gt;
    &amp;lt;% else %&amp;gt;
      &amp;lt;span class=&amp;quot;none&amp;quot;&amp;gt;None given&amp;lt;/span&amp;gt;
    &amp;lt;% end %&amp;gt;
    &amp;lt;/dd&amp;gt;
    &amp;lt;dt&amp;gt;Twitter:&amp;lt;/dt&amp;gt;
    &amp;lt;dd&amp;gt;
    &amp;lt;% if @user.twitter_name.present? %&amp;gt;
      &amp;lt;%= link_to @user.twitter_name, &amp;crarr;
  &amp;quot;http://twitter.com/#{@user.twitter_name}&amp;quot; %&amp;gt;
    &amp;lt;% else %&amp;gt;
      &amp;lt;span class=&amp;quot;none&amp;quot;&amp;gt;None given&amp;lt;/span&amp;gt;
    &amp;lt;% end %&amp;gt;
    &amp;lt;/dd&amp;gt;
    &amp;lt;dt&amp;gt;Bio:&amp;lt;/dt&amp;gt;
    &amp;lt;dd&amp;gt;
    &amp;lt;% if @user.bio.present? %&amp;gt;
      &amp;lt;%=raw Redcarpet.new(@user.bio, :hard_wrap, :filter_html, &amp;crarr;
        :autolink).to_html %&amp;gt;
    &amp;lt;% else %&amp;gt;
      &amp;lt;span class=&amp;quot;none&amp;quot;&amp;gt;None given&amp;lt;/span&amp;gt;
    &amp;lt;% end %&amp;gt;
    &amp;lt;/dd&amp;gt;
  &amp;lt;/dl&amp;gt;
&amp;lt;/div&amp;gt;&lt;/pre&gt;

&lt;p&gt;As this logic is view-related we can&amp;rsquo;t really extract it out into the model. One solution for this would be to use helper methods. We already use one called &lt;code&gt;image_tag&lt;/code&gt; in this template to render the avatar. Let&amp;rsquo;s take a look at it.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/helpers/users_helper.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;module UsersHelper
  def avatar_name(user)
    if user.avatar_image_name.present?
      user.avatar_image_name
    else
      &amp;quot;default.png&amp;quot;
    end
  end
end&lt;/pre&gt;

&lt;p&gt;This helper method determines whether the current user has an avatar and returns the name of a default image if they don&amp;rsquo;t. We could extract more of the logic from the view into helper methods but the problem with is that they&amp;rsquo;re simple methods in a global namespace; there&amp;rsquo;s nothing object-orientated about them.&lt;/p&gt;

&lt;h3&gt;Installing Draper&lt;/h3&gt;

&lt;p&gt;This scenario is a good case for using a presenter, or a decorator as Draper refers to them, so let&amp;rsquo;s add it to our application. The Draper gem is installed in the usual way, by adding it to the &lt;code&gt;Gemfile&lt;/code&gt; then 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;http://rubygems.org&amp;#x27;

gem &amp;#x27;rails&amp;#x27;, &amp;#x27;3.1.0&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;quot;  ~&amp;gt; 3.1.0&amp;quot;
  gem &amp;#x27;coffee-rails&amp;#x27;, &amp;quot;~&amp;gt; 3.1.0&amp;quot;
  gem &amp;#x27;uglifier&amp;#x27;
end

gem &amp;#x27;jquery-rails&amp;#x27;
gem &amp;#x27;redcarpet&amp;#x27;

gem &amp;#x27;draper&amp;#x27;&lt;/pre&gt;

&lt;p&gt;Once Draper has installed we&amp;rsquo;ll create a decorator for our &lt;code&gt;User&lt;/code&gt; model by running the &lt;code&gt;draper:decorator&lt;/code&gt; generator.&lt;/p&gt;

&lt;pre class="ruby"&gt;$ rails g draper:decorator user
      create  app/decorators
      create  app/decorators/application_decorator.rb
      create  app/decorators/user_decorator.rb&lt;/pre&gt;
      
&lt;p&gt;As this is our first decorator an &lt;code&gt;application_decorator&lt;/code&gt; will also be generated. Any decorators we generate inherit from ApplicationDecorator so we can place any functionality that we want to share across decorators there.&lt;/p&gt; 

&lt;p&gt;The &lt;code&gt;UserDecorator&lt;/code&gt; class is fairly straightforward, consisting mainly of comments that explain how it works. We&amp;rsquo;ll dive right in and start using it to clean up our templates.&lt;/p&gt;

&lt;h3&gt;Tidying Up The Profile Page&lt;/h3&gt;

&lt;p&gt;To use Draper in our profile page we first need to make a change to the &lt;code&gt;show&lt;/code&gt; action in the &lt;code&gt;UsersController&lt;/code&gt;. This action currently fetches a &lt;code&gt;User&lt;/code&gt; in the usual way.&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
  def index
    @users = User.all
  end

  def show
    @user = User.find(params[:id])
  end
end&lt;/pre&gt;

&lt;p&gt;We need to wrap this user in our decorator which we do by replacing &lt;code&gt;User.find&lt;/code&gt; with &lt;code&gt;UserDecorator.find&lt;/code&gt;.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/controllers/users_controller.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;def show
  @user = UserDecorator.find(params[:id])
end&lt;/pre&gt;

&lt;p&gt;This code will now return a &lt;code&gt;UserDecorator&lt;/code&gt; instance that wraps the &lt;code&gt;User&lt;/code&gt; record and delegates all methods to it by default (more on this later). The action will still work as it did before even though we&amp;rsquo;re working with a &lt;code&gt;UserDecorator&lt;/code&gt; instead of a &lt;code&gt;User&lt;/code&gt;. Now we can start to clean up our views and we&amp;rsquo;ll begin with the code that renders the user&amp;rsquo;s avatar.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/users/show.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;%= link_to_if @user.url.present?, image_tag( &amp;crarr; 
  &amp;quot;avatars/#{avatar_name(@user)}&amp;quot;, class: &amp;quot;avatar&amp;quot;), @user.url %&amp;gt;&lt;/pre&gt;
  
&lt;p&gt;We&amp;rsquo;ll replace this in the view with this:&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/users/show.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;%= @user.avatar %&amp;gt;&lt;/pre&gt;

&lt;p&gt;This code will look for an avatar method in the &lt;code&gt;UserDecorator&lt;/code&gt; which we&amp;rsquo;ll write next. There are some things we&amp;rsquo;ll need to be aware of  when writing this method. Whenever we call a helper method from a decorator, such as our &lt;code&gt;link_to_if&lt;/code&gt; method, we need to call it through the &lt;code&gt;h&lt;/code&gt; method (this stands for &amp;ldquo;helpers&amp;rdquo;). When we want to reference the model we call &lt;code&gt;model&lt;/code&gt; instead of, in this case, &lt;code&gt;@user&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The code we&amp;rsquo;ve copied from the the view into &lt;code&gt;avatar&lt;/code&gt; calls the &lt;code&gt;avatar_name&lt;/code&gt; helper method. As we&amp;rsquo;re calling &lt;code&gt;avatar_name&lt;/code&gt; from our decorator we&amp;rsquo;ll move it there from the &lt;code&gt;UsersHelper&lt;/code&gt; class. Now that we have the method in the same class we don&amp;rsquo;t need to pass it a &lt;code&gt;User&lt;/code&gt; and we can replace its calls to user with model.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/decorators/user_decorator.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;class UserDecorator &amp;lt; ApplicationDecorator
  decorates :user
  
  def avatar
    h.link_to_if model.url.present?, h.image_tag(&amp;quot;avatars/#{avatar_name}&amp;quot;, class: &amp;quot;avatar&amp;quot;), model.url
  end
  
  private
  def avatar_name
    if model.avatar_image_name.present?
      model.avatar_image_name
    else
      &amp;quot;default.png&amp;quot;
    end
  end
end&lt;/pre&gt;

&lt;p&gt;Next we&amp;rsquo;ll tidy up the code that render&amp;rsquo;s the user&amp;rsquo;s name. We&amp;rsquo;ll replace this code in the view:&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;&amp;lt;%= link_to_if @user.url.present?, (@user.full_name.present? ? @user.full_name : @user.username), @user.url %&amp;gt;&amp;lt;/h1&amp;gt;&lt;/pre&gt;
 
&lt;p&gt;with this:&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;&amp;lt;%= @user.linked_name %&amp;gt;&amp;lt;/h1&amp;gt;&lt;/pre&gt;

&lt;p&gt;We&amp;rsquo;ll need to write the &lt;code&gt;linked_name&lt;/code&gt; method in the &lt;code&gt;UserDecorator&lt;/code&gt;. There are similarities between the code we&amp;rsquo;ve taken from the template and the &lt;code&gt;avatar&lt;/code&gt; method we wrote earlier; both of these render a link whose content is dependent on whether the user&amp;rsquo;s &lt;code&gt;url&lt;/code&gt; if it&amp;rsquo;s present. As we&amp;rsquo;re in a class it&amp;rsquo;s easy to refactor this duplication out.&lt;/p&gt;

&lt;p&gt;To handle the link creation we&amp;rsquo;ll create a new private method called &lt;code&gt;site_link&lt;/code&gt;, which takes the content as a parameter. We can then call this method in both the &lt;code&gt;avatar&lt;/code&gt; and &lt;code&gt;linked_name&lt;/code&gt; methods to tidy them up. As before we replace any calls to &lt;code&gt;@user&lt;/code&gt; in the &lt;code&gt;linked_name&lt;/code&gt; with &lt;code&gt;model&lt;/code&gt;. With all that done our decorator now looks like this.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;app/decorators/user_decorator.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;class UserDecorator &amp;lt; ApplicationDecorator
  decorates :user
  
  def avatar
    site_link h.image_tag(&amp;quot;avatars/#{avatar_name}&amp;quot;, &amp;crarr;
      class: &amp;quot;avatar&amp;quot;)
  end
  
  def linked_name
    site_link(model.full_name.present? ? model.full_name : &amp;crarr;
      model.username)
  end
  
  private
  def site_link(content)
    h.link_to_if model.url.present?, content, model.url
  end
  
  def avatar_name
    if model.avatar_image_name.present?
      model.avatar_image_name
    else
      &amp;quot;default.png&amp;quot;
    end
  end
end&lt;/pre&gt;

&lt;p&gt;If we reload a user&amp;rsquo;s profile page now it should look just as it did before.&lt;/p&gt;

&lt;p&gt;Our template is already looking a lot cleaner but there&amp;rsquo;s more we can do yet. Next we&amp;rsquo;ll refactor a larger chunk of the view code, the code that renders a link to the user&amp;rsquo;s website.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/user/show.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;dt&amp;gt;Website:&amp;lt;/dt&amp;gt;
&amp;lt;dd&amp;gt;
  &amp;lt;% if @user.url.present? %&amp;gt;
    &amp;lt;%= link_to @user.url, @user.url %&amp;gt;
  &amp;lt;% else %&amp;gt;
    &amp;lt;span class=&amp;quot;none&amp;quot;&amp;gt;None given&amp;lt;/span&amp;gt;
  &amp;lt;% end %&amp;gt;
&amp;lt;/dd&amp;gt;&lt;/pre&gt;

&lt;p&gt;We&amp;rsquo;ll replace this with:&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/user/show.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;dt&amp;gt;Website:&amp;lt;/dt&amp;gt;
&amp;lt;dd&amp;gt;&amp;lt;%= @user.website %&amp;gt;&amp;lt;/dd&amp;gt;&lt;/pre&gt;

&lt;p&gt;As before we&amp;rsquo;ll create a method in the decorator class. We can see from the code that we&amp;rsquo;ve removed from the view that if the user has no &lt;code&gt;url&lt;/code&gt; then some HTML is rendered. We could just return this as a string but we don&amp;rsquo;t want to put raw HTML into a Ruby string. Another solution would be to move the code into a partial and to render that, but as we only to output a single HTML element it makes more sense to use the &lt;code&gt;content_tag&lt;/code&gt; helper method.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/decorators/user_decorator.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;def website
  if model.url.present?
    h.link_to model.url, model.url
  else
    h.content_tag :span, &amp;quot;None given&amp;quot;, class: &amp;quot;none&amp;quot;
  end  
end&lt;/pre&gt;

&lt;p&gt;We can do a similar thing for the two parts of the template that render the Twitter information and the user&amp;rsquo;s biography. We won&amp;rsquo;t show the details of that here, but after we&amp;rsquo;ve made the changes our view code will looks a lot cleaner.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/views/users/show.html.erb&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;div id=&amp;quot;profile&amp;quot;&amp;gt;
  &amp;lt;%= @user.avatar %&amp;gt;
  &amp;lt;h1&amp;gt;&amp;lt;%= @user.linked_name %&amp;gt;&amp;lt;/h1&amp;gt;
  &amp;lt;dl&amp;gt;
    &amp;lt;dt&amp;gt;Username:&amp;lt;/dt&amp;gt;
    &amp;lt;dd&amp;gt;&amp;lt;%= @user.username %&amp;gt;&amp;lt;/dd&amp;gt;
    &amp;lt;dt&amp;gt;Member Since:&amp;lt;/dt&amp;gt;
    &amp;lt;dd&amp;gt;&amp;lt;%= @user.member_since %&amp;gt;&amp;lt;/dd&amp;gt;
    &amp;lt;dt&amp;gt;Website:&amp;lt;/dt&amp;gt;
    &amp;lt;dd&amp;gt;&amp;lt;%= @user.website %&amp;gt;&amp;lt;/dd&amp;gt;
    &amp;lt;dt&amp;gt;Twitter:&amp;lt;/dt&amp;gt;
    &amp;lt;dd&amp;gt;&amp;lt;%= @user.twitter %&amp;gt;&amp;lt;/dd&amp;gt;
    &amp;lt;dt&amp;gt;Bio:&amp;lt;/dt&amp;gt;
    &amp;lt;dd&amp;gt;&amp;lt;%= @user.bio %&amp;gt;&amp;lt;/dd&amp;gt;
  &amp;lt;/dl&amp;gt;
&amp;lt;/div&amp;gt;&lt;/pre&gt;

&lt;p&gt;The new &lt;code&gt;twitter&lt;/code&gt; and &lt;code&gt;bio&lt;/code&gt; methods in the decorator look like this:&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/decorators/user_decorator.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;def website
  if model.url.present?
    h.link_to model.url, model.url
  else
    h.content_tag :span, &amp;quot;None given&amp;quot;, class: &amp;quot;none&amp;quot;
  end  
end

def twitter
  if model.twitter_name.present?
    h.link_to model.twitter_name, &amp;crarr;  
      &amp;quot;http://twitter.com/#{model.twitter_name}&amp;quot;
  else
    h.content_tag :span, &amp;quot;None given&amp;quot;, class: &amp;quot;none&amp;quot;
  end
end
  
def bio
  if model.bio.present?
    Redcarpet.new(model.bio, :hard_wrap, :filter_html, &amp;crarr;
 		:autolink).to_html.html_safe
  else
    h.content_tag :span, &amp;quot;None given&amp;quot;, class: &amp;quot;none&amp;quot;
  end
end&lt;/pre&gt;

&lt;p&gt;The two new methods look very similar to each other and also to the &lt;code&gt;website&lt;/code&gt; method we wrote earlier. There&amp;rsquo;s a fair amount of duplication between the three methods, especially in each &lt;code&gt;else&lt;/code&gt; clause, so it would be good if we could extract this part out into its own method.&lt;/p&gt;

&lt;p&gt;We can use a block to help with this. We&amp;rsquo;ll extract the &lt;code&gt;else&lt;/code&gt; clause out into its own method which we&amp;rsquo;ll call &lt;code&gt;handle_none&lt;/code&gt;. We&amp;rsquo;ll pass the value we want to check the presence of to this method and also a block. If the value is present the code in the block will be executed, otherwise the span tag will be rendered. We can then use this &lt;code&gt;handle_none&lt;/code&gt; to tidy up the website, &lt;code&gt;twitter&lt;/code&gt; and &lt;code&gt;bio&lt;/code&gt; methods.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/decorators/user_decorator.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;def website
  handle_none model.url do
    h.link_to model.url, model.url
  end  
end
  
def twitter
  handle_none model.twitter_name do
    h.link_to model.twitter_name, &amp;crarr; 
      &amp;quot;http://twitter.com/#{model.twitter_name}&amp;quot;
  end
end
  
def bio
  handle_none model.bio do
    Redcarpet.new(model.bio, :hard_wrap, :filter_html, &amp;crarr;
      :autolink).to_html.html_safe
  end
end
  
private
def handle_none(value)
  if value.present?
    yield
  else
    h.content_tag :span, &amp;quot;None given&amp;quot;, class: &amp;quot;none&amp;quot;
  end
end&lt;/pre&gt;

&lt;p&gt;Another change we could make it to extract the Markdown rendering into the &lt;code&gt;ApplicationDecorator&lt;/code&gt; so that we can call it from any other decorators we might make.  We&amp;rsquo;ll create a new &lt;code&gt;markdown&lt;/code&gt; method there now that will render any text we pass to it.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/decorators/application_decorator.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;class ApplicationDecorator &amp;lt; Draper::Base
  def markdown(text)
    Redcarpet.new(text, :hard_wrap, :filter_html, &amp;crarr; 
      :autolink).to_html.html_safe
  end
end&lt;/pre&gt;

&lt;p&gt;Now in the &lt;code&gt;UserDecorator&lt;/code&gt; we can now modify the &lt;code&gt;bio&lt;/code&gt; method so that it calls &lt;code&gt;markdown&lt;/code&gt;.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/decorators/user_decorator.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;def bio
  handle_none model.bio do
    markdown(model.bio)
  end
end&lt;/pre&gt;

&lt;h3&gt;Modifying The Model&lt;/h3&gt;

&lt;p&gt;Now that we have the decorator in place it&amp;rsquo;s a good idea to look through the model layer for any view-related code that we can move up to the relevant decorator. For example in our &lt;code&gt;User&lt;/code&gt; model we have a &lt;code&gt;member_since&lt;/code&gt; method that formats the user&amp;rsquo;s &lt;code&gt;created_at&lt;/code&gt; time. This code can be considered view-related as all it does is return a formatted string so we&amp;rsquo;ll move it to the decorator.&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 member_since
    created_at.strftime(&amp;quot;%B %e, %Y&amp;quot;)
  end
end&lt;/pre&gt;

&lt;p&gt;All we need to do is move the method to the decorator and prepend &lt;code&gt;model&lt;/code&gt; before &lt;code&gt;created_at&lt;/code&gt;.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/decorators/user_decorator.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;def member_since
  model.created_at.strftime(&amp;quot;%B %e, %Y&amp;quot;)
end&lt;/pre&gt;

&lt;h3&gt;Restricting Access To The Model With The &lt;code&gt;allows&lt;/code&gt; Method&lt;/h3&gt;

&lt;p&gt;While we&amp;rsquo;re modifying the &lt;code&gt;UserDecorator&lt;/code&gt; there&amp;rsquo;s one more feature of Draper that we&amp;rsquo;ll demonstrate: the &lt;code&gt;allows&lt;/code&gt; method. As it stands the &lt;code&gt;UserDecorator&lt;/code&gt; will delegate all of its methods to the &lt;code&gt;User&lt;/code&gt; object, but we can choose which methods are 
delegated to the &lt;code&gt;User&lt;/code&gt; model by using &lt;code&gt;allows&lt;/code&gt; and passing it the name of the methods we want to delegate.&lt;/p&gt;

&lt;p class="codeFilePath"&gt;/app/decorators/user_decorator.rb&lt;/p&gt;
&lt;pre class="ruby"&gt;class UserDecorator &amp;lt; ApplicationDecorator
  decorates :user
  allows :username

  # Other methods omitted
end&lt;/pre&gt;

&lt;p&gt;We&amp;rsquo;ll allow only &lt;code&gt;username&lt;/code&gt; to be delegated and this way only the &lt;code&gt;username&lt;/code&gt; method will be delegated down to the User model. This is the only method we need to delegate as it&amp;rsquo;s the only method that&amp;rsquo;s called in the view that doesn&amp;rsquo;t come from the decorator. This gives us more control over the decorator&amp;rsquo;s interface.&lt;/p&gt; 

&lt;p&gt;Now that we&amp;rsquo;re done with refactoring everything out to the decorator we&amp;rsquo;ll try loading a user&amp;rsquo;s profile page again to make sure that everything still looks the same.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/749/original/E286I03.png" width="800" height="583" alt="The full user profile page looks the same after our changes."/&gt;
&lt;/div&gt;

&lt;p&gt;It does. We can even check our other user and that still looks the same too but our view code is much cleaner.&lt;/p&gt;

&lt;div class="imageWrapper"&gt;
  &lt;img src="/system/photos/750/original/E286I04.png" width="800" height="469" alt="The profile page for MrMystery is unchanged, too."/&gt;
&lt;/div&gt;

&lt;p&gt;By using a decorator our show template has been reduced from 1050 bytes in 34 lines to 382 bytes in 16 lines, a reduction in size of almost two thirds. It looks much cleaner too and we&amp;rsquo;ve made it much easier to edit should we want to change the layout of the page.&lt;/p&gt;</description>
      <pubDate>Wed, 05 Oct 2011 17:42:31 +0000</pubDate>
      <guid>http://asciicasts.com/episodes/286-draper</guid>
      <link>http://asciicasts.com/episodes/286-draper</link>
    </item>
  </channel>
</rss>

