Adventures In Codinghttp://adventuresincoding.com
Kevin Faustino's technical blog about Ruby, Ruby on Rails, and JavaScript2015-03-03 22:10:23 +0000Now writing at The Remarkable Labs Bloghttp://feedproxy.google.com/~r/AdventuresInCoding/~3/XRVc_NauDw8/now-writing-at-the-remarkable-labs-blog
Mon, 29 Oct 2012 19:35:50 +0000http://adventuresincoding.com/2012/10/now-writing-at-the-remarkable-labs-blog<p>As some of you have noticed, Adventures in Coding has been missing in action for a while. This is because over the last couple of months, I have been starting a new Ruby on Rails consultancy based in Toronto, Ontario. The company is called <a href="http://www.remarkablelabs.com">Remarkable Labs</a>.</p>
<p>This past week, I launched the company blog at <a href="http://blog.remarkablelabs.com">http://blog.remarkablelabs.com</a>. This is where I will continue sharing knowledge and tips about Ruby and various other technologies.</p>
<p>Adventures in Coding will remain online as a reference, but I will no longer be actively posting here. You can subscribe to the Remarkable Labs blog <a href="http://feeds.feedburner.com/remarkablelabs">here</a>.</p>
<p>Thanks,
Kevin Faustino</p><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/XRVc_NauDw8" height="1" width="1" alt=""/>http://adventuresincoding.com/2012/10/now-writing-at-the-remarkable-labs-blogA review of "The Rails View" by Bruce Williams and John Athaydehttp://feedproxy.google.com/~r/AdventuresInCoding/~3/QJQ-ywyCw2U/a-review-of-the-rails-view-by-bruce-williams-and-john-athayde
Tue, 05 Jun 2012 10:44:17 +0000http://adventuresincoding.com/2012/06/a-review-of-the-rails-view-by-bruce-williams-and-john-athayde<p><a href="http://pragprog.com/book/warv/the-rails-view"><em>The Rails View: Create a Beautiful and Maintainable User Experience</em></a> is a book published by the Pragmatic Bookshelf by <a href="https://twitter.com/wbruce">Bruce Williams</a> and <a href="http://www.boboroshi.com">John Athayde</a>. It is the most comprehensive resource on the view layer in Ruby on Rails available, clocking in at 264 pages and 9 chapters.</p>
<p>The book explains each concept to the reader by building an application <em>ArtFlow</em>. Each chapter builds upon the content in the previous, and provides a good sense of the order in which things should be done while developing.</p>
<p>Despite the fact that I have been working with Rails for years, I found the book to be an excellent reference and filled with things I wasn&#39;t aware of. For example, having read multiple HTML5 books, I was surprised to discover <code>&lt;aside&gt;</code> tags are not to be used for layout sidebars. While some of the chapters were introductions to technologies such as Sass, the authors always provided enough tips and links to further explore each topic. </p>
<h2>Who Should Read It?</h2>
<ul>
<li>Anybody working with Ruby and maintain views for web applications. While some of the chapters are Ruby on Rails specific, many of these concepts can be applied to any Ruby web framework such as Sinatra. </li>
<li>Rails developers looking for a great reference for building a maintainable view layer.</li>
<li>Experienced Rails developers looking to learn a couple new tips and tricks.</li>
</ul>
<h2>The Chapters</h2>
<p>Here is a list of what is covered in <em>The Rails View</em>:</p>
<ol>
<li>Creating an Application Layout</li>
<li>Improving Readability</li>
<li>Adding Cascading Style Sheets</li>
<li>Adding JavaScript</li>
<li>Building Maintainable Forms</li>
<li>Using Presenters</li>
<li>Handling Mobile Views</li>
<li>Working with Email</li>
<li>Optimizing Performance </li>
</ol>
<h2>Beautiful Markup</h2>
<p>When reading the book, I was constantly reminded of a presentation I watched on the Envy Labs Blog named <a href="http://blog.envylabs.com/2010/06/beautiful-markup">&quot;Beautiful Markup&quot;</a></p>
<p>Only after taking a look at the video again did I realaize that it was done by co-author of <em>The Rails View</em>, John Athayde.</p>
<p>While the presentation is from 2010, it is a great compliment to the book. Many of the topics are still relevent today and are expanded upon in the book.</p>
<div class="video-container">
<iframe id="viddler-a7681a7b" src="//www.viddler.com/embed/a7681a7b/?f=1&autoplay=0&player=full&loop=false&nologo=false&hd=false" width="545" height="451" frameborder="0" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
</div>
<h2>Verdict</h2>
<p>If you are developing Ruby on Rails applications for a living, you should pick up <em>The Rails View</em>. While some areas may be to introductory for some developers, there will always be enough new knowledge to be discovered that more than pays for the book.</p><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/QJQ-ywyCw2U" height="1" width="1" alt=""/>http://adventuresincoding.com/2012/06/a-review-of-the-rails-view-by-bruce-williams-and-john-athaydeUsing elasticsearch with Herokuhttp://feedproxy.google.com/~r/AdventuresInCoding/~3/3PCejuylZbY/using-elasticsearch-with-heroku
Thu, 31 May 2012 18:18:30 +0000http://adventuresincoding.com/2012/05/using-elasticsearch-with-heroku<p>In my previous post, I wrote about <a href="http://adventuresincoding.com/2012/05/full-text-search-in-rails-using-elasticsearch">how to integrate elasticsearch in a Ruby on Rails application</a>. The next step after you have everything up and running is to deploy your app to production. I will detail how to do this via Heroku, since <a href="http://www.elasticsearch.org/tutorials/2012/03/21/deploying-elasticsearch-with-chef-solo.html">other deployment strategies</a> have been well documented.</p>
<h2>Bonsai ElasticSearch</h2>
<p>Heroku has a wide variety of addons including Bonsai ElasticSearch. Bonsai allows you to have an elasticsearch server without having to write a single line of configuration. Add the addon to your application via the command-line:</p>
<div class="highlight"><pre><span class="nv">$ </span>heroku addons:add bonsai:test
</pre>
</div>
<h2>Configuring Tire to work with Bonsai</h2>
<p>Nick Zadrozny wrote a <a href="https://gist.github.com/2041121">gist</a> detailing a technique he used to use Bonsai in production and a local elasticsearch server for development. </p>
<p>To begin, we are going to create an initializer that sets a constant <code>BONSAI_INDEX_NAME</code> that will be used by our indexed model. First we determine if an environment variable is set for <code>BONSAI_INDEX_URL</code>. The <code>BONSAI_INDEX_URL</code> is the address of your Bonasi elasticsearch server. If present, we configure <code>Tire</code> to use <a href="http://index.bonsai.io">http://index.bonsai.io</a> as the base url for our elasticsearch calls and set our index name to the unique bonasi id found in the address. Otherwise, we use the technique described in my <a href="http://adventuresincoding.com/2012/05/full-text-search-in-rails-using-elasticsearch">previous post</a> to ensure a unique index per environment.</p>
<div class="highlight"><pre><span class="c1"># config/initializers/bonsai.rb</span>
<span class="k">if</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;BONSAI_INDEX_URL&#39;</span><span class="o">]</span>
<span class="no">Tire</span><span class="o">.</span><span class="n">configure</span> <span class="k">do</span>
<span class="n">url</span> <span class="s2">&quot;http://index.bonsai.io&quot;</span>
<span class="k">end</span>
<span class="no">BONSAI_INDEX_NAME</span> <span class="o">=</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;BONSAI_INDEX_URL&#39;</span><span class="o">][</span><span class="sr">/[^\/]+$/</span><span class="o">]</span>
<span class="k">else</span>
<span class="n">app_name</span> <span class="o">=</span> <span class="no">Rails</span><span class="o">.</span><span class="n">application</span><span class="o">.</span><span class="n">class</span><span class="o">.</span><span class="n">parent_name</span><span class="o">.</span><span class="n">underscore</span><span class="o">.</span><span class="n">dasherize</span>
<span class="no">BONSAI_INDEX_NAME</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">app_name</span><span class="si">}</span><span class="s2">-</span><span class="si">#{</span><span class="no">Rails</span><span class="o">.</span><span class="n">env</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">end</span>
</pre>
</div>
<p>Next update the <code>index_name</code> set on your indexed model to use <code>BONSAI_INDEX_NAME</code>.</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Post</span>
<span class="o">.</span><span class="n">.</span><span class="o">.</span>
<span class="n">index_name</span> <span class="no">BONSAI_INDEX_NAME</span>
<span class="k">end</span>
</pre>
</div>
<p>At this point, your application is ready for deployment to Heroku.</p>
<h2>Indexing</h2>
<p>Once you deploy your Heroku application, you must create and populate the elasticsearch index. We do this by running the Heroku console and entering the following code:</p>
<div class="highlight"><pre><span class="no">Post</span><span class="o">.</span><span class="n">create_elasticsearch_index</span> <span class="c1"># Post is our example model</span>
<span class="no">Tire</span><span class="o">.</span><span class="n">index</span> <span class="no">BONSAI_INDEX_NAME</span> <span class="k">do</span>
<span class="n">import</span> <span class="no">Post</span><span class="o">.</span><span class="n">all</span>
<span class="n">refresh</span>
<span class="k">end</span>
</pre>
</div>
<p>Once your index is in place, test your application on production to see if you are receiving search results. </p>
<h2>Final Note</h2>
<p>The Bonasi addon is in public beta at the time of writing. This is just a word of warning if you have a mission critical application and you wanted to try elasticsearch out.</p><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/3PCejuylZbY" height="1" width="1" alt=""/>http://adventuresincoding.com/2012/05/using-elasticsearch-with-herokuFull-Text Search in Rails using elasticsearchhttp://feedproxy.google.com/~r/AdventuresInCoding/~3/5BTlJwJxbnE/full-text-search-in-rails-using-elasticsearch
Wed, 30 May 2012 20:06:26 +0000http://adventuresincoding.com/2012/05/full-text-search-in-rails-using-elasticsearch<p>Searching on websites is important from a content discovery and user usability perspective. It allows readers to control the way they look for content instead of navigating through menus. Given this blog was missing full-text search, I decided to implement it using elasticsearch. Here is a detailed step-by-step guide on how I did that using outside-in development.</p>
<h2>elasticsearch</h2>
<p><a href="http://www.elasticsearch.org/">elasticsearch</a> is a distributed open source search server based on Apache Lucene. It allows for real-time searching and the ability to scale easily through replicas. Getting started is easy as elasticsearch is schema less. You only have to pass it a typed JSON document and it will automatically be indexed for you. Types are automatically determined by the server. It also allows you to define your own mappings to set boost levels, analyzers, and types.</p>
<h2>Blog Engine Background</h2>
<p>The code examples are in the post are extracted from the Adventures in Coding blog engine source code. It is a Ruby on Rails 3.1 application with a MongoDB database. All testing is done via Cucumber and RSpec. Views and CSS are generated with Haml and Sass respectively.</p>
<h2>Getting Started</h2>
<p>The first step in getting started is running an elasticsearch server locally for development. I do all my development on a Mac, so I easily installed it via <code>homebrew</code>:</p>
<div class="highlight"><pre><span class="nv">$ </span>brew install elasticsearch
</pre>
</div>
<p>If you are running another platform, you can build elasticsearch from <a href="http://www.elasticsearch.org/download/">source</a>.</p>
<p>Once installed, I launched the server running:</p>
<div class="highlight"><pre><span class="nv">$ </span>elasticsearch -f -D es.config<span class="o">=</span>/usr/local/Cellar/elasticsearch/0.19.3/config/elasticsearch.yml
</pre>
</div>
<h2>Tire</h2>
<p>Knowing that I am going to need a elasticsearch client, I selected the most popular Ruby client <a href="https://github.com/karmi/tire">Tire</a>. It is actively maintained, has a large amount of users, and also integrates nicely with Rails and ActiveModel.</p>
<p>To add it to the project, I added it to my <em>Gemfile</em>, and ran <code>bundle</code>.</p>
<div class="highlight"><pre><span class="c1"># Gemfile</span>
<span class="n">gem</span> <span class="s1">&#39;tire&#39;</span>
</pre>
</div>
<h2>Search Feature</h2>
<p>Now that everything is setup, I defined my Cucumber &quot;Search&quot; feature and scenarios which will drive development.</p>
<div class="highlight"><pre><span class="c"># features/search.feature</span><span class="nf"></span>
<span class="k">Feature:</span><span class="nf"> Search</span>
<span class="nf"> As a User</span>
<span class="nf"> I want to search for content</span>
<span class="nf"> In order to find content easily over paginating</span>
<span class="nf"> </span><span class="k">Background:</span><span class="nf"></span>
<span class="k"> Given </span><span class="nf">I am on the home page</span>
<span class="nf"> </span><span class="k">Scenario:</span><span class="nf"> Find posts by content</span>
<span class="k"> Given </span><span class="nf">the following posts:</span>
<span class="k"> |</span><span class="s"> title</span><span class="k"> |</span><span class="nf"></span>
<span class="k"> |</span><span class="s"> Demon in a Bottle</span><span class="k"> |</span><span class="nf"></span>
<span class="k"> |</span><span class="s"> Extremis</span><span class="k"> |</span><span class="nf"></span>
<span class="nf"> </span><span class="k">When </span><span class="nf">I search for &quot;</span><span class="s">Demon</span><span class="nf">&quot;</span>
<span class="nf"> </span><span class="k">Then </span><span class="nf">I should be on the search page</span>
<span class="nf"> </span><span class="k">And </span><span class="nf">I should see the post called &quot;</span><span class="s">Demon in a Bottle</span><span class="nf">&quot; in the post list</span>
<span class="nf"> </span><span class="k">But </span><span class="nf">I should not see the post called &quot;</span><span class="s">Extremis</span><span class="nf">&quot; in the post list</span>
<span class="nf"> </span><span class="k">Scenario:</span><span class="nf"> No posts found</span>
<span class="k"> When </span><span class="nf">I search for &quot;</span><span class="s">Armor Wars</span><span class="nf">&quot;</span>
<span class="nf"> </span><span class="k">Then </span><span class="nf">I should be on the search page</span>
<span class="nf"> </span><span class="k">And </span><span class="nf">I should see a message indicating no posts were found</span>
</pre>
</div>
<p>When I ran <code>cucumber</code>, my search scenarios failed because I haven&#39;t defined two step definitions. Cucumber informs me of this with the following output:</p>
<div class="highlight"><pre><span class="nf">You can implement step definitions for undefined steps with these snippets:</span>
<span class="k">When </span><span class="nf">/^I search for &quot;</span><span class="s">([^</span><span class="nf">&quot;]*)&quot;</span><span class="s">$/ do |arg1|</span>
<span class="s"> pending # express the regexp above with the code you wish you had</span>
<span class="s">end</span>
<span class="s">Then /^I should see a message indicating no posts were found$/ do</span>
<span class="s"> pending # express the regexp above with the code you wish you had</span>
<span class="s">end</span>
</pre>
</div>
<p>Wanting to keep all search related step definitions together to keep things organized, I created the file <em>features/step_definitions/search_steps.rb</em>:</p>
<div class="highlight"><pre><span class="c"># features/step_definitions/search_steps.rb</span><span class="nf"></span>
<span class="k">When </span><span class="nf">/^I search for &quot;</span><span class="s">([^</span><span class="nf">&quot;]*)&quot;</span><span class="s">$/ do |query|</span>
<span class="s"> fill_in &#39;query&#39;, with: query</span>
<span class="s"> click_button &#39;Search&#39;</span>
<span class="s">end</span>
<span class="s">Then /^I should see a message indicating no posts were found$/ do</span>
<span class="s"> within(&#39;section.posts&#39;) do</span>
<span class="s"> page.should have_content(&#39;No posts were found&#39;)</span>
<span class="s"> end</span>
<span class="s">end</span>
</pre>
</div>
<p>Running <code>cucumber</code> again indicated that it couldn&#39;t find a query text field in the markup.</p>
<div class="highlight"><pre><span class="k">When </span><span class="nf">I search for &quot;</span><span class="s">Demon</span><span class="nf">&quot; </span><span class="c"># features/step_definitions/search_steps.rb:1</span><span class="nf"></span>
<span class="nf"> cannot fill in, no text field, text area or password field with id, name, or label &#39;query&#39; found (Capybara::ElementNotFound)</span>
</pre>
</div>
<p>To solve this, I needed to create a new search controller, a form to submit the search query, and a search index view.
Once implemented, Cucumber would be able to successfully interact with the search form and endpoints. Since I hadn&#39;t wired up the <code>Post</code> model to <code>Tire</code> yet, the scenarios were still failing.</p>
<h3>Search Form</h3>
<div class="highlight"><pre><span class="nt">%section</span><span class="p">{</span> <span class="nb">id</span><span class="p">:</span> <span class="s1">&#39;search&#39;</span> <span class="p">}</span>
<span class="p">=</span> <span class="n">form_tag</span> <span class="n">search_path</span><span class="p">,</span> <span class="nb">method</span><span class="p">:</span> <span class="ss">:get</span> <span class="k">do</span>
<span class="p">=</span> <span class="n">text_field_tag</span> <span class="ss">:query</span><span class="p">,</span> <span class="n">params</span><span class="o">[</span><span class="ss">:query</span><span class="o">]</span><span class="p">,</span> <span class="n">autocomplete</span><span class="p">:</span> <span class="ss">:off</span><span class="p">,</span> <span class="n">placeholder</span><span class="p">:</span> <span class="s1">&#39;e.g. Ruby&#39;</span>
<span class="p">=</span> <span class="n">submit_tag</span><span class="p">(</span><span class="s1">&#39;Search&#39;</span><span class="p">)</span>
</pre>
</div>
<h3>Controller</h3>
<div class="highlight"><pre><span class="c1"># app/controllers/search_controller.rb</span>
<span class="k">class</span> <span class="nc">SearchController</span> <span class="o">&lt;</span> <span class="no">ApplicationController</span>
<span class="k">def</span> <span class="nf">index</span>
<span class="vi">@posts</span> <span class="o">=</span> <span class="o">[]</span>
<span class="k">end</span>
<span class="k">end</span>
</pre>
</div>
<h3>Route</h3>
<div class="highlight"><pre><span class="c1"># config/routes.rb:</span>
<span class="n">get</span> <span class="s1">&#39;search&#39;</span><span class="p">,</span> <span class="n">to</span><span class="p">:</span> <span class="s1">&#39;search#index&#39;</span>
</pre>
</div>
<h3>Helper</h3>
<div class="highlight"><pre><span class="c1"># app/helpers/posts_helper.rb:</span>
<span class="k">module</span> <span class="nn">PostsHelper</span>
<span class="k">def</span> <span class="nf">render_posts</span><span class="p">(</span><span class="n">posts</span><span class="p">)</span>
<span class="k">if</span> <span class="n">posts</span><span class="o">.</span><span class="n">to_a</span><span class="o">.</span><span class="n">size</span> <span class="o">&gt;</span> <span class="mi">0</span>
<span class="n">render</span><span class="p">(</span><span class="n">posts</span><span class="p">)</span>
<span class="k">else</span>
<span class="n">content_tag</span><span class="p">(</span><span class="ss">:div</span><span class="p">,</span> <span class="s2">&quot;No posts were found&quot;</span><span class="p">,</span> <span class="n">class</span><span class="p">:</span> <span class="s1">&#39;message&#39;</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</pre>
</div>
<h3>Search index view</h3>
<div class="highlight"><pre><span class="nt">%section</span><span class="nc">.posts</span><span class="p">=</span> <span class="n">render_posts</span><span class="p">(</span><span class="vi">@posts</span><span class="p">)</span>
</pre>
</div>
<h2>Adding Tire to ActiveModel</h2>
<p>To make my <code>Post</code> model searchable, I included two modules:</p>
<div class="highlight"><pre> <span class="kp">include</span> <span class="no">Tire</span><span class="o">::</span><span class="no">Model</span><span class="o">::</span><span class="no">Search</span>
<span class="kp">include</span> <span class="no">Tire</span><span class="o">::</span><span class="no">Model</span><span class="o">::</span><span class="no">Callbacks</span>
</pre>
</div>
<p>Now when I save a document, it will automatically create/update the elasticsearch index.</p>
<p>Since I am running elasticsearch in both my test and development environments, I needed to create a unique elasticsearch index name per environment. This ensured when I ran my Cucumber features, that my development indexes were not wiped out. I accomplished this by setting <code>index_name</code> to <code>&quot;blog-engine-#{Rails.env}&quot;</code>.</p>
<p>I also wanted control of what attributes are sent to Tire for indexing. If Tire finds a <code>to_indexed_json</code> method on your model, it will use that over <code>to_json</code>. I decided to index the model _id, title, content, and published_at date.</p>
<p>Finally instead of relying on a dynamic schema, I defined a mapping which is explicit in how posts are analyzed and scored. </p>
<ul>
<li>Fields such as _id and published_at are indexed, but not analyzed. </li>
<li>Post title&#39;s are given a boost rating of 100 over the default 1.0.</li>
<li>Blog post text fields are analyzed with a <a href="http://www.elasticsearch.org/guide/reference/index-modules/analysis/snowball-analyzer.html">snowball analyzer</a>.</li>
</ul>
<p>Here is the final <em>app/models/post.rb</em> code:</p>
<div class="highlight"><pre><span class="k">class</span> <span class="nc">Post</span>
<span class="o">.</span><span class="n">.</span><span class="o">.</span>
<span class="kp">include</span> <span class="no">Tire</span><span class="o">::</span><span class="no">Model</span><span class="o">::</span><span class="no">Search</span>
<span class="kp">include</span> <span class="no">Tire</span><span class="o">::</span><span class="no">Model</span><span class="o">::</span><span class="no">Callbacks</span>
<span class="n">index_name</span> <span class="s2">&quot;blog-engine-</span><span class="si">#{</span><span class="no">Rails</span><span class="o">.</span><span class="n">env</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="n">mapping</span> <span class="k">do</span>
<span class="n">indexes</span> <span class="ss">:_id</span><span class="p">,</span> <span class="n">index</span><span class="p">:</span> <span class="ss">:not_analyzed</span>
<span class="n">indexes</span> <span class="ss">:title</span><span class="p">,</span> <span class="n">analyzer</span><span class="p">:</span> <span class="s1">&#39;snowball&#39;</span><span class="p">,</span> <span class="n">boost</span><span class="p">:</span> <span class="mi">100</span>
<span class="n">indexes</span> <span class="ss">:content</span><span class="p">,</span> <span class="n">analyzer</span><span class="p">:</span> <span class="s1">&#39;snowball&#39;</span>
<span class="n">indexes</span> <span class="ss">:published_at</span><span class="p">,</span> <span class="n">type</span><span class="p">:</span> <span class="s1">&#39;date&#39;</span><span class="p">,</span> <span class="n">index</span><span class="p">:</span> <span class="ss">:not_analyzed</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">to_indexed_json</span>
<span class="p">{</span>
<span class="n">_id</span><span class="p">:</span> <span class="n">_id</span><span class="p">,</span>
<span class="n">title</span><span class="p">:</span> <span class="n">title</span><span class="p">,</span>
<span class="n">content</span><span class="p">:</span> <span class="n">content</span><span class="p">,</span>
<span class="n">published_at</span><span class="p">:</span> <span class="n">published_at</span>
<span class="p">}</span><span class="o">.</span><span class="n">to_json</span>
<span class="k">end</span>
<span class="o">.</span><span class="n">.</span><span class="o">.</span>
<span class="k">end</span>
</pre>
</div>
<h2>Handling requests to elasticsearch from RSpec</h2>
<p>To ensure no outside HTTP requests to elasticsearch are made when running specs, I added a dependency to <a href="https://github.com/bblimke/webmock">webmock</a>.</p>
<p>To install <code>webmock</code> add it to your <em>Gemfile</em> under the test group:</p>
<div class="highlight"><pre><span class="c1"># Gemfile</span>
<span class="n">group</span> <span class="ss">:test</span> <span class="k">do</span>
<span class="n">gem</span> <span class="s1">&#39;webmock&#39;</span><span class="p">,</span> <span class="nb">require</span><span class="p">:</span> <span class="kp">nil</span>
<span class="k">end</span>
</pre>
</div>
<p>In my <em>spec/spec_helper.rb</em> file, I required the webmock library and stubbed out any request to the elasticsearch server (http://localhost:9200) in a before filter.</p>
<p>Here is an abbreviated version of my <em>specs/spec_helper.rb</em>:</p>
<div class="highlight"><pre><span class="no">ENV</span><span class="o">[</span><span class="s2">&quot;RAILS_ENV&quot;</span><span class="o">]</span> <span class="o">||=</span> <span class="s1">&#39;test&#39;</span>
<span class="nb">require</span> <span class="no">File</span><span class="o">.</span><span class="n">expand_path</span><span class="p">(</span><span class="s2">&quot;../../config/environment&quot;</span><span class="p">,</span> <span class="bp">__FILE__</span><span class="p">)</span>
<span class="nb">require</span> <span class="s1">&#39;rspec/rails&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;webmock/rspec&#39;</span>
<span class="o">.</span><span class="n">.</span><span class="o">.</span>
<span class="no">RSpec</span><span class="o">.</span><span class="n">configure</span> <span class="k">do</span> <span class="o">|</span><span class="n">config</span><span class="o">|</span>
<span class="n">config</span><span class="o">.</span><span class="n">before</span> <span class="ss">:each</span> <span class="k">do</span>
<span class="n">stub_request</span><span class="p">(</span><span class="ss">:post</span><span class="p">,</span> <span class="sr">/.*localhost:9200\/.*/</span><span class="p">)</span><span class="o">.</span><span class="n">to_return</span><span class="p">(</span><span class="n">body</span><span class="p">:</span> <span class="s2">&quot;{}&quot;</span><span class="p">)</span>
<span class="no">Mongoid</span><span class="o">.</span><span class="n">purge!</span>
<span class="k">end</span>
<span class="k">end</span>
</pre>
</div>
<p>If you are interested in finding out more about <code>webmock</code>, be sure to read the <a href="https://github.com/bblimke/webmock">README</a> on GitHub.</p>
<h2>Handling search calls to elasticsearch</h2>
<p>Finally, I need to implement a method that actually used elasticsearch to search for posts. I didn&#39;t want the method to live in my Post model, so I created a class <code>PostRepository</code>. I did this to keep view specific logic, such as pagination, away from my domain models.</p>
<p><code>PostRepository</code> takes a hash of params from a controller. Using those params, it will extract the query and current page of results. </p>
<div class="highlight"><pre><span class="c1"># app/models/post_repository.rb</span>
<span class="k">class</span> <span class="nc">PostRepository</span>
<span class="no">POSTS_PER_PAGE</span> <span class="o">=</span> <span class="mi">5</span>
<span class="kp">attr_accessor</span> <span class="ss">:params</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
<span class="nb">self</span><span class="o">.</span><span class="n">params</span> <span class="o">=</span> <span class="n">params</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">search</span>
<span class="n">query</span> <span class="o">=</span> <span class="n">params</span><span class="o">[</span><span class="ss">:query</span><span class="o">]</span>
<span class="n">model</span><span class="o">.</span><span class="n">tire</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="nb">load</span><span class="p">:</span> <span class="kp">true</span><span class="p">,</span> <span class="n">page</span><span class="p">:</span> <span class="n">params</span><span class="o">[</span><span class="ss">:page</span><span class="o">]</span><span class="p">,</span> <span class="n">per_page</span><span class="p">:</span> <span class="no">POSTS_PER_PAGE</span><span class="p">)</span> <span class="k">do</span>
<span class="n">query</span> <span class="p">{</span> <span class="n">string</span> <span class="n">query</span><span class="p">,</span> <span class="n">default_operator</span><span class="p">:</span> <span class="s2">&quot;AND&quot;</span> <span class="p">}</span> <span class="k">if</span> <span class="n">query</span><span class="o">.</span><span class="n">present?</span>
<span class="n">filter</span> <span class="ss">:range</span><span class="p">,</span> <span class="n">published_at</span><span class="p">:</span> <span class="p">{</span> <span class="n">lte</span><span class="p">:</span> <span class="no">Time</span><span class="o">.</span><span class="n">zone</span><span class="o">.</span><span class="n">now</span> <span class="p">}</span>
<span class="n">sort</span> <span class="p">{</span> <span class="n">by</span> <span class="ss">:published_at</span><span class="p">,</span> <span class="s2">&quot;desc&quot;</span> <span class="p">}</span> <span class="k">if</span> <span class="n">query</span><span class="o">.</span><span class="n">blank?</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="kp">protected</span>
<span class="k">def</span> <span class="nf">model</span>
<span class="no">Post</span>
<span class="k">end</span>
<span class="k">end</span>
</pre>
</div>
<p>Here is a breakdown of what is occurs in the search method:</p>
<ul>
<li>I accessed the Tire search method from the <code>Post.tire</code> accessor.</li>
<li>Passing in option <code>load: true</code> to <code>search</code> queries the database for the models. If you store all your attributes in elasticsearch then this isn&#39;t needed. </li>
<li> <code>query { string query, default_operator: &quot;AND&quot; } if query.present?</code>: I query elasticsearch for the query string passed by the user. This string is analyzed using a AND operator.</li>
<li><code>filter :range, published_at: { lte: Time.zone.now }</code>: I ensure that only published articles are returned in the results by filtering for dates less than or equal to the current time.</li>
<li><code>sort { by :published_at, &quot;desc&quot; } if query.blank?</code>: If a user enters no query string, I return the results in descending order of their published date.</li>
</ul>
<p>I also updated the search_controller to use the new search method:</p>
<div class="highlight"><pre><span class="c"># app/controllers/search_controller.rb</span>
<span class="nb">class</span> <span class="n">SearchController</span> <span class="o">&lt;</span> <span class="n">ApplicationController</span>
<span class="n">def</span> <span class="nb">index</span>
<span class="p">@</span><span class="n">posts</span> <span class="p">=</span> <span class="n">PostRepository</span><span class="p">.</span><span class="n">new</span><span class="p">(</span><span class="n">params</span><span class="p">).</span><span class="n">search</span>
<span class="k">end</span>
<span class="k">end</span>
</pre>
</div>
<h2>Returning to Cucumber</h2>
<p>Running the Cucumber search scenarios still resulted in failure. One of the main reasons is that I was not creating the Post index on each scenario run. To fix this, I added a <code>Before</code> hook to delete all existing indexes and recreate them based on my mappings.</p>
<div class="highlight"><pre><span class="c1"># features/support/hooks.rb</span>
<span class="no">Before</span> <span class="k">do</span>
<span class="no">Post</span><span class="o">.</span><span class="n">tire</span><span class="o">.</span><span class="n">index</span><span class="o">.</span><span class="n">delete</span>
<span class="no">Post</span><span class="o">.</span><span class="n">create_elasticsearch_index</span>
<span class="k">end</span>
</pre>
</div>
<p>The features ran again, but still ended up in failure. Calls to elasticsearch were being done asynchronously, whereas my scenarios were being executed synchronously. The solution was to add a synchronization point in the code somewhere. The best place I thought was before any search execution. I updated the step definition <code>/^I search for &quot;([^&quot;]*)&quot;$/</code> to include an index refresh call <code>Post.tire.index.refresh</code>. This step definition would be executed after any data has been setup in a <code>Given</code> step.</p>
<div class="highlight"><pre><span class="c1"># features/step_definitions/search_steps.rb</span>
<span class="no">When</span> <span class="sr">/^I search for &quot;([^&quot;]*)&quot;$/</span> <span class="k">do</span> <span class="o">|</span><span class="n">query</span><span class="o">|</span>
<span class="no">Post</span><span class="o">.</span><span class="n">tire</span><span class="o">.</span><span class="n">index</span><span class="o">.</span><span class="n">refresh</span>
<span class="n">fill_in</span> <span class="s1">&#39;query&#39;</span><span class="p">,</span> <span class="n">with</span><span class="p">:</span> <span class="n">query</span>
<span class="n">click_button</span> <span class="s1">&#39;Search&#39;</span>
<span class="k">end</span>
<span class="o">.</span><span class="n">.</span><span class="o">.</span>
</pre>
</div>
<p>Running <code>cucumber</code> again resulted in success:</p>
<div class="highlight"><pre><span class="k">Feature:</span><span class="nf"> Search</span>
<span class="nf"> As a User</span>
<span class="nf"> I want to search for content</span>
<span class="nf"> In order to find content easily over paginating</span>
<span class="nf"> </span><span class="k">Background:</span><span class="nf"></span>
<span class="k"> Given </span><span class="nf">I am on the home page </span>
<span class="nf"> </span><span class="k">Scenario:</span><span class="nf"> Find posts by content </span>
<span class="k"> Given </span><span class="nf">the following posts: </span>
<span class="k"> |</span><span class="s"> title</span><span class="k"> |</span><span class="nf"></span>
<span class="k"> |</span><span class="s"> Demon in a Bottle</span><span class="k"> |</span><span class="nf"></span>
<span class="k"> |</span><span class="s"> Extremis</span><span class="k"> |</span><span class="nf"></span>
<span class="nf"> </span><span class="k">When </span><span class="nf">I search for &quot;</span><span class="s">Demon</span><span class="nf">&quot; </span>
<span class="nf"> </span><span class="k">Then </span><span class="nf">I should be on the search page </span>
<span class="nf"> </span><span class="k">And </span><span class="nf">I should see the post called &quot;</span><span class="s">Demon in a Bottle</span><span class="nf">&quot; in the post list</span>
<span class="nf"> </span><span class="k">But </span><span class="nf">I should not see the post called &quot;</span><span class="s">Extremis</span><span class="nf">&quot; in the post list</span>
<span class="nf"> </span><span class="k">Scenario:</span><span class="nf"> No posts found </span>
<span class="k"> When </span><span class="nf">I search for &quot;</span><span class="s">Armor Wars</span><span class="nf">&quot; </span>
<span class="nf"> </span><span class="k">Then </span><span class="nf">I should be on the search page </span>
<span class="nf"> </span><span class="k">And </span><span class="nf">I should see a message indicating no posts were found</span>
<span class="s">2</span><span class="nf"> scenarios (</span><span class="s">2</span><span class="nf"> passed)</span>
<span class="s">10</span><span class="nf"> steps (</span><span class="s">10</span><span class="nf"> passed)</span>
<span class="s">0</span><span class="nf">m</span><span class="s">1.315</span><span class="nf">s</span>
</pre>
</div>
<h2>After thoughts</h2>
<p>I love developing outside-in as it allows you to know your progress every step of the development process. The process shown in this post was not your typical Cucumber example. Adding external services as a dependency to your integration test suite is something I always try to avoid. However, having the confidence that I will always know if my features are working outweighs that negative. </p>
<p>Also, be sure to read about <a href="http://adventuresincoding.com/2012/05/using-elasticsearch-with-heroku">using elasticsearch witin Heroku</a>.</p><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/5BTlJwJxbnE" height="1" width="1" alt=""/>http://adventuresincoding.com/2012/05/full-text-search-in-rails-using-elasticsearchHow to configure Cucumber and RSpec to work with Mongoid 3.0http://feedproxy.google.com/~r/AdventuresInCoding/~3/jaUxedNvI5s/how-to-configure-cucumber-and-rspec-to-work-with-mongoid-30
Mon, 28 May 2012 21:07:11 +0000http://adventuresincoding.com/2012/05/how-to-configure-cucumber-and-rspec-to-work-with-mongoid-30<p>With the upcoming release of <a href="http://mongoid.org/en/mongoid/index.html">Mongoid 3.0</a>, I have decided to update a <a href="http://adventuresincoding.com/2010/07/how-to-configure-cucumber-and-rspec-to-work-with-mongoid">previous post</a> about getting Mongoid to play nice with RSpec and Cucumber.</p>
<p>RSpec and Cucumber by default are setup to work with relational databases using ActiveRecord. To get them to work with Mongoid, we had previously run: <code>Mongoid.master.collections.select {|c| c.name !~ /system/ }.each(&amp;:drop)</code> in before hooks. The previous line will no longer work in Mongoid 3.0, as we now access databases via sessions. As of Mongoid version 2.0.2, the method <code>Mongoid.purge!</code> was added to easily drop all collections and indexes from your MongoDB database. This is what you should use moving forward.</p>
<h2>RSpec</h2>
<p>The following example <em>spec_helper.rb</em> file is the bare minimum you will need to get Mongoid running with RSpec:</p>
<div class="highlight"><pre><span class="c1"># spec_helper.rb</span>
<span class="no">ENV</span><span class="o">[</span><span class="s2">&quot;RAILS_ENV&quot;</span><span class="o">]</span> <span class="o">||=</span> <span class="s1">&#39;test&#39;</span>
<span class="nb">require</span> <span class="no">File</span><span class="o">.</span><span class="n">expand_path</span><span class="p">(</span><span class="s2">&quot;../../config/environment&quot;</span><span class="p">,</span> <span class="bp">__FILE__</span><span class="p">)</span>
<span class="nb">require</span> <span class="s1">&#39;rspec/rails&#39;</span>
<span class="c1"># Requires supporting ruby files with custom matchers and macros, etc,</span>
<span class="c1"># in spec/support/ and its subdirectories.</span>
<span class="no">Dir</span><span class="o">[</span><span class="no">Rails</span><span class="o">.</span><span class="n">root</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s2">&quot;spec/support/**/*.rb&quot;</span><span class="p">)</span><span class="o">].</span><span class="n">each</span> <span class="p">{</span><span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="nb">require</span> <span class="n">f</span><span class="p">}</span>
<span class="no">RSpec</span><span class="o">.</span><span class="n">configure</span> <span class="k">do</span> <span class="o">|</span><span class="n">config</span><span class="o">|</span>
<span class="n">config</span><span class="o">.</span><span class="n">mock_with</span> <span class="ss">:rspec</span>
<span class="n">config</span><span class="o">.</span><span class="n">before</span> <span class="ss">:each</span> <span class="k">do</span>
<span class="no">Mongoid</span><span class="o">.</span><span class="n">purge!</span>
<span class="k">end</span>
<span class="k">end</span>
</pre>
</div>
<h2>Cucumber</h2>
<p>Cucumber allows defining hooks in any file under the <em>features/support</em> directory. To setup Cucumber, create a file <em>features/support/hooks.rb</em> that will drop your MongoDB collections before each scenario:</p>
<div class="highlight"><pre><span class="c1"># features/support/hooks.rb</span>
<span class="no">Before</span> <span class="k">do</span> <span class="o">|</span><span class="n">scenario</span><span class="o">|</span>
<span class="no">Mongoid</span><span class="o">.</span><span class="n">purge!</span>
<span class="k">end</span>
</pre>
</div><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/jaUxedNvI5s" height="1" width="1" alt=""/>http://adventuresincoding.com/2012/05/how-to-configure-cucumber-and-rspec-to-work-with-mongoid-30Easily deploy to multiple environments on Heroku with heroku_sanhttp://feedproxy.google.com/~r/AdventuresInCoding/~3/SgHvZUUwuaw/easily-deploy-to-multiple-environments-on-heroku-with-herokusan
Sat, 26 May 2012 00:59:28 +0000http://adventuresincoding.com/2012/05/easily-deploy-to-multiple-environments-on-heroku-with-herokusan<p>Deploying to <a href="http://www.heroku.com/">Heroku</a> is one of the easiest things a Rails developer can experience. All you have to do is push your git repository to heroku master. As easy as this is, it is not ideal for applications with staging and production environments.</p>
<p>One of the most popular gems available to handle this issue is <a href="https://github.com/fastestforward/heroku_san">heroku_san</a></p>
<h2>Install</h2>
<p>Add the following to your project <em>Gemfile</em>:</p>
<div class="highlight"><pre><span class="n">group</span> <span class="ss">:development</span> <span class="k">do</span>
<span class="n">gem</span> <span class="s1">&#39;heroku_san&#39;</span>
<span class="k">end</span>
</pre>
</div>
<p>Once you run <code>bundle install</code> to add <code>heroku_san</code> to your application, you will need to generate a heroku configuration file.</p>
<p>Geneate <em>config/heroku.yml</em> via the heroku_san generator:</p>
<div class="highlight"><pre><span class="nv">$ </span>bundle <span class="nb">exec </span>rails generate heroku_san
</pre>
</div>
<h2>config/heroku.yml</h2>
<p>The power of <code>heroku_san</code> over the standard heroku deploy method is that it allows you to define all your environment variables and addons in one place. These settings can be shared with all environments or specific ones.</p>
<p>Here is a modified version of the adventuresincoding configuration file:</p>
<div class="highlight"><pre><span class="l-Scalar-Plain">production</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">app</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">adventuresincoding</span>
<span class="l-Scalar-Plain">stack</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">cedar</span>
<span class="l-Scalar-Plain">config</span><span class="p-Indicator">:</span> <span class="nl">&amp;default_config</span>
<span class="l-Scalar-Plain">BUNDLE_WITHOUT</span><span class="p-Indicator">:</span> <span class="s">&quot;test:development&quot;</span>
<span class="l-Scalar-Plain">addons</span><span class="p-Indicator">:</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">mongolab:starter</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">newrelic:standard</span>
<span class="l-Scalar-Plain">staging</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">app</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">adventuresincoding-staging</span>
<span class="l-Scalar-Plain">stack</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">cedar</span>
<span class="l-Scalar-Plain">config</span><span class="p-Indicator">:</span>
<span class="l-Scalar-Plain">&lt;&lt;</span><span class="p-Indicator">:</span> <span class="nv">*default_config</span>
<span class="l-Scalar-Plain">RAILS_ENV</span><span class="p-Indicator">:</span> <span class="s">&#39;staging&#39;</span>
<span class="l-Scalar-Plain">addons</span><span class="p-Indicator">:</span>
<span class="p-Indicator">-</span> <span class="l-Scalar-Plain">mongolab:starter</span>
</pre>
</div>
<h2>Setup</h2>
<p>To setup your Heroku environments, run the following commands:</p>
<div class="highlight"><pre><span class="nv">$ </span>bundle <span class="nb">exec </span>rake all heroku:create
<span class="nv">$ </span>bundle <span class="nb">exec </span>rake all heroku:config
<span class="nv">$ </span>bundle <span class="nb">exec </span>rake all heroku:addons
</pre>
</div>
<p>The above commands will create all your applications, configuration variables, and addons specified in your <em>heroku.yml</em>. When using the rake task <em>all</em>, commands are executed on each of your Heroku applications. If you want to only run commands on certain environments, use the name of the environment instead of <em>all</em>.</p>
<h2>Deploying</h2>
<p>heroku_san comes with a wide variety of <em>rake</em> tasks to manage your applications. One of those being <code>heroku:deploy</code></p>
<p>For example, to deploy to staging, run:</p>
<div class="highlight"><pre><span class="nv">$ </span>bundle <span class="nb">exec </span>rake staging heroku:deploy
</pre>
</div>
<h2>Benefits</h2>
<p>Using <code>heroku_san</code> provides you the benefit of keeping all your deployment logic in one place. This allows you to easily keep track of the differences in configuration variables and addons between environments. It was also an essential piece of the puzzle when I migrated from the bamboo stack to cedar. </p><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/SgHvZUUwuaw" height="1" width="1" alt=""/>http://adventuresincoding.com/2012/05/easily-deploy-to-multiple-environments-on-heroku-with-herokusanManaging your web applications with Foremanhttp://feedproxy.google.com/~r/AdventuresInCoding/~3/L3WmePHSamE/managing-your-web-applications-with-foreman
Fri, 25 May 2012 18:21:42 +0000http://adventuresincoding.com/2012/05/managing-your-web-applications-with-foreman<p>Not all applications are created equal. While some applications can be as simple as a Ruby on Rails web app connecting to a database, others may have dependencies such as background workers. David Dollar realized his web applications were getting a lot more complicated to run, which resulted in him creating <a href="https://github.com/ddollar/foreman">Foreman</a>. Foreman is an excellent tool which allows you to encompass your entire application structure in a <code>Procfile</code>. A <code>Procfile</code> allows you to declare multiple processes that encompass your application and run them all with a single <code>foreman start</code> command. </p>
<h2>Procfile</h2>
<p>A <code>Procfile</code> is a list that contains a name to identify the process and the command used by the system to run it. Foreman will look for it by default in your project&#39;s root directory.</p>
<p>Here is an example <code>Procfile</code> of a Ruby on Rails application running Resque workers in the background:</p>
<div class="highlight"><pre><span class="n">web</span><span class="p">:</span> <span class="n">bundle</span> <span class="nb">exec</span> <span class="n">thin</span> <span class="n">start</span> <span class="o">-</span><span class="nb">p</span> <span class="vg">$PORT</span>
<span class="n">worker</span><span class="p">:</span> <span class="n">bundle</span> <span class="nb">exec</span> <span class="n">rake</span> <span class="n">resque</span><span class="ss">:work</span> <span class="no">QUEUE</span><span class="o">=*</span>
</pre>
</div>
<h2>Getting Started</h2>
<p>Once your <code>Procfile</code> is in place, install the <code>foreman</code> gem:</p>
<div class="highlight"><pre><span class="nv">$ </span>gem install foreman
</pre>
</div>
<p>To start up your application from the command line, all you need to do is run <code>foreman start</code>. By default, this will run one instance of the each application type defined in your <code>Procfile</code>.</p>
<h2>Concurrency</h2>
<p>Foreman supports the ability to run more than 1 process of each type via the concurrency <code>-c</code> parameter. You must define the number of each process type to run.</p>
<p>For example, to increase the number of worker processes to two, execute:</p>
<div class="highlight"><pre><span class="nv">$ </span>foreman start -c <span class="nv">web</span><span class="o">=</span>1,worker<span class="o">=</span>2
</pre>
</div>
<h2>.env</h2>
<p>Another great benefit to Foreman is the ability to define local ENV variables for development. By creating a <code>.env</code> file in the root directory of the project, Foreman will load all key/value pairs specified in the file into the default environment. </p>
<div class="highlight"><pre><span class="n">S3_KEY</span><span class="p">=</span><span class="n">abc</span>
<span class="n">S3_SECRET</span><span class="p">=</span><span class="n">def</span>
</pre>
</div>
<p>Be sure to include <code>.env</code> in your <code>.gitignore</code> file as well to ensure sensitive information is not stored in your repository.</p>
<h2>Procfile.development</h2>
<p>Sometimes you will want a different <code>Procfile</code> for development . For example, you may want to run redis on your local machine while developing your application to save system resources. A convention I use is that I suffix <em>.development</em> to my development <code>Procfile</code>.</p>
<div class="highlight"><pre><span class="c1"># Procfile.development</span>
<span class="n">web</span><span class="p">:</span> <span class="n">bundle</span> <span class="nb">exec</span> <span class="n">thin</span> <span class="n">start</span> <span class="o">-</span><span class="nb">p</span> <span class="vg">$PORT</span>
<span class="n">redis</span><span class="p">:</span> <span class="n">redis</span><span class="o">-</span><span class="n">server</span> <span class="sr">/usr/</span><span class="n">local</span><span class="o">/</span><span class="n">etc</span><span class="o">/</span><span class="n">redis</span><span class="o">.</span><span class="n">conf</span>
<span class="n">worker</span><span class="p">:</span> <span class="n">bundle</span> <span class="nb">exec</span> <span class="n">rake</span> <span class="n">resque</span><span class="ss">:work</span> <span class="no">QUEUE</span><span class="o">=*</span>
</pre>
</div>
<p>To run Foreman with a different <code>Procfile</code>, run <code>foreman</code> with the -f parameter:</p>
<div class="highlight"><pre><span class="nv">$ </span>foreman start -f Procfile.development
</pre>
</div>
<h2>Further Reading</h2>
<p>For more information, check out the following:</p>
<ul>
<li><a href="http://ddollar.github.com/foreman/">Man Page</a></li>
<li><a href="https://devcenter.heroku.com/articles/procfile">Declaring and Scaling Process Types with Procfile</a></li>
<li><a href="http://blog.daviddollar.org/2011/05/06/introducing-foreman.html">Introducing Foreman</a></li>
</ul><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/L3WmePHSamE" height="1" width="1" alt=""/>http://adventuresincoding.com/2012/05/managing-your-web-applications-with-foremanHow to get ApacheBench(ab) to work on Mac OS X Lionhttp://feedproxy.google.com/~r/AdventuresInCoding/~3/jPqaSmivLwg/how-to-get-apachebenchab-to-work-on-mac-os-x-lion
Wed, 16 May 2012 16:23:18 +0000http://adventuresincoding.com/2012/05/how-to-get-apachebenchab-to-work-on-mac-os-x-lion<p>ApacheBench is a tool to do lightweight performance benchmarking on web applications. It is part of Apache which ships by default with Mac OS X. However, Mac OS X Lion comes with a version that has some issues.</p>
<p>Here is an example of benchmark running against a local Ruby on Rails application:</p>
<div class="highlight"><pre><span class="nv">$ </span>ab -n 100 -c5 http://127.0.0.1:3000/
This is ApacheBench, Version 2.3 &lt;<span class="nv">$Revision</span>: 655654 <span class="nv">$&gt;</span>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 <span class="o">(</span>be patient<span class="o">)</span>...Send request failed!
Send request failed!
apr_socket_recv: Connection reset by peer <span class="o">(</span>54<span class="o">)</span>
</pre>
</div>
<p>A majority of the times when <em>ab</em> is run, you will receive an <code>apr_socket_recv</code> error on Lion.</p>
<h2>Solution</h2>
<p>To fix the issue with ApacheBench, we must replace the version on the system with one which is more recent.</p>
<h3>Step 1: Download the latest version of apache</h3>
<p>At the time of writing, the latest version of Apache availble is 2.4.2. You can find it and future versions at <a href="http://apache.mirrors.pair.com/httpd/">http://apache.mirrors.pair.com/httpd/</a>.</p>
<div class="highlight"><pre><span class="nv">$ </span>curl -O http://apache.mirrors.pair.com/httpd/httpd-2.4.2.tar.gz
</pre>
</div>
<h3>Step 2: Install missing dependencies</h3>
<p>If you attempt to build Apache without installing <em>pcre</em>, you will get the following error: <code>configure: error: pcre-config for libpcre not found. PCRE is required and available from http://pcre.org/</code>. </p>
<p>Install pcre via <a href="https://github.com/mxcl/homebrew">Homebrew</a>:</p>
<div class="highlight"><pre><span class="nv">$ </span>brew install pcre
</pre>
</div>
<h3>Step 3: Build Apache</h3>
<p>Once downloaded, extract and build the downloaded version of Apache:</p>
<div class="highlight"><pre><span class="nv">$ </span>tar xzvf httpd-2.4.2.tar.gz
<span class="nv">$ </span><span class="nb">cd </span>httpd-2.4.2/
<span class="nv">$ </span>./configure
<span class="nv">$ </span>make
</pre>
</div>
<h3>Step 4: Replace ab</h3>
<p>Replace the existing ApacheBench(ab) version on Mac OS X Lion with the newly built version:</p>
<div class="highlight"><pre><span class="nv">$ </span>sudo cp support/ab /usr/sbin
</pre>
</div><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/jPqaSmivLwg" height="1" width="1" alt=""/>http://adventuresincoding.com/2012/05/how-to-get-apachebenchab-to-work-on-mac-os-x-lionThe future of Adventures in Codinghttp://feedproxy.google.com/~r/AdventuresInCoding/~3/DAK_LL7ZF6g/the-future-of-adventures-in-coding
Tue, 08 May 2012 16:27:26 +0000http://adventuresincoding.com/2012/05/the-future-of-adventures-in-coding<p>Over the course of the last year I had the feeling something was missing. There are a lot of factors that contribute to developer happiness such as their environment, work, and their team. One piece that I felt was missing from my day-to-day life was the joy I had when I shared something I&#39;ve learned with the community. Moving forward, I plan on sharing as much as I can on adventuresincoding.com.</p>
<h2>The Mission Statement</h2>
<p>Before I sit down on the keyboard to write anything, I will reflect on this statement: </p>
<blockquote>
<p>&quot;Sharing experiences, opinions, &amp; news for the ruby web developer&quot;</p>
</blockquote>
<p>If something doesn&#39;t fall within the mission statement, it will not make it on the blog.</p>
<h2>What can you expect</h2>
<p>Knowledge is sparse around the web for Ruby developers. I want to transform this site to be a hub for experienced and new Ruby developers alike.</p>
<p>Here is a list of what I&#39;m planning:</p>
<ul>
<li>Tutorials</li>
<li>Tips &amp; Tricks</li>
<li>Opinions on code, team dynamics, and growing software craftsmanship in our communities</li>
<li>Focus on things I feel are of interest to myself and others. This includes Backbone.js, Rails, testing, and good code practices in general</li>
<li>Sharing news about our industry</li>
<li>Sharing experiments and implementation details of this blog engine</li>
<li>Updating older posts which have outdated information and code</li>
</ul><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/DAK_LL7ZF6g" height="1" width="1" alt=""/>http://adventuresincoding.com/2012/05/the-future-of-adventures-in-codingSpeed up your websites with Smusherhttp://feedproxy.google.com/~r/AdventuresInCoding/~3/T1NM276FtdU/speed-up-your-websites-with-smusher
Fri, 18 Nov 2011 13:54:06 +0000http://adventuresincoding.com/2011/11/speed-up-your-websites-with-smusher<p>Images are a bulk of the load time for many sites. There are many techniques that can allow for less requests, such as creating CSS Sprites. While I believe these techniques are essential, clients will still have to download the images in the end.</p>
<p>Saving your images with Photoshop&#39;s &quot;Save for Web &amp; Devices&quot; doesn&#39;t ensure that they are truly optimized. However, there are ways to get smaller images without quality loss.</p>
<h2>&quot;Lossless&quot; images</h2>
<p>Using optimization techniques, images can be optimized to smaller sizes without effecting their visual quality.</p>
<p><a href="http://www.smushit.com/ysmush.it/">Yahoo! SmushIt</a> and <a href="http://punypng.com">PunyPNG</a> are two great services on the web that allow you to upload images and receive byte reduced versions.</p>
<h2>Smusher</h2>
<p>Using the above mentioned services requires manually selecting files and uploading them to the web. Thanks to Michael Grosser, we now have Smusher, a Ruby CLI for lossless reduction of your images.</p>
<p>Smusher will take an image or directory of images and process them through an image reduction service with just a single line in your terminal.</p>
<p>To install it, run the following:</p>
<div class="highlight"><pre><span class="nv">$ </span>gem install smusher
</pre>
</div>
<p>By default, smusher uses <a href="http://www.smushit.com/ysmush.it/">Yahoo! SmushIt</a>, but also has to option to switch to the PunyPng service.</p>
<h2>Usage</h2>
<p>To process a directory of images, run the <code>smusher</code> command:</p>
<div class="highlight"><pre><span class="nv">$ </span>smusher public/images --service PunyPng
</pre>
</div>
<p>To demonstrate the savings, I ran smusher on a <a href="http://upload.wikimedia.org/wikipedia/en/d/de/Ruby-%28programming-language%29-logo-2008.png">Ruby logo</a> found on Wikipedia:</p>
<div class="highlight"><pre>smushing Ruby-<span class="o">(</span>programming-language<span class="o">)</span>-logo-2008.png
27416 -&gt; <span class="nv">23544</span> <span class="o">=</span> 85%
</pre>
</div>
<p>Smusher saved us 15% on just one image. Multiply that by every image on your site, and you will have made your users a little more happy with faster page downloads.</p>
<h2>.puny_png_api_key</h2>
<p>If you are a PunyPNG service subscriber, you can store your api key for future usage by smusher.</p>
<p>Add a file named <em>.puny_png_api_key</em> to your home directory with your PunyPNG api key as it&#39;s contents.</p>
<h2>Use it</h2>
<p>Smusher is a great tool that has been available for years and I feel is not really known to most web developers. Once you start using it, I truly believe it will be a part of your utility belt.</p><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/T1NM276FtdU" height="1" width="1" alt=""/>http://adventuresincoding.com/2011/11/speed-up-your-websites-with-smusherGetting Inherited Resources 1.2.1 and Mongoid to play nicehttp://feedproxy.google.com/~r/AdventuresInCoding/~3/51VmC1PD6_g/getting-inherited-resources-121-and-mongoid-to-play-nice
Sun, 20 Mar 2011 19:27:30 +0000http://adventuresincoding.com/2011/03/getting-inherited-resources-121-and-mongoid-to-play-nice<p>With the release of version 1.2.1 of <a href="https://github.com/josevalim/inherited_resources">Inherited Resources</a>, compatibility with <a href="http://www.mongoid.org">Mongoid</a> was broken. To optimize the setting of a collection in a controller, Inherited Resources calls the <code>scoped</code> method at the end of the collection association chain over calling <code>all</code>. The change to use <code>scoped</code> results in a collection being lazily queried. The reason why Mongoid breaks is because it does not have a <code>scoped</code> method, thus using Inherited Resources in any Mongoid project causes collection controller actions to break. </p>
<p>Inherited Resources has rectified the issue in their <em>master</em> branch on GitHub by checking to see if the collection responds to <code>scoped</code>. If you cannot wait for the next release of Inherited Resources, add the following code to one of your Rails initializers to get it working with Mongoid again:</p>
<div class="highlight"><pre><span class="c1"># app/config/initializers/inherited_resources.rb</span>
<span class="k">module</span> <span class="nn">InheritedResources</span>
<span class="k">class</span> <span class="nc">Base</span>
<span class="k">def</span> <span class="nf">collection</span>
<span class="n">get_collection_ivar</span> <span class="o">||</span> <span class="k">begin</span>
<span class="n">c</span> <span class="o">=</span> <span class="n">end_of_association_chain</span>
<span class="n">set_collection_ivar</span><span class="p">(</span><span class="n">c</span><span class="o">.</span><span class="n">respond_to?</span><span class="p">(</span><span class="ss">:scoped</span><span class="p">)</span> <span class="p">?</span> <span class="n">c</span><span class="o">.</span><span class="n">scoped</span> <span class="p">:</span> <span class="n">c</span><span class="o">.</span><span class="n">all</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</pre>
</div><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/51VmC1PD6_g" height="1" width="1" alt=""/>http://adventuresincoding.com/2011/03/getting-inherited-resources-121-and-mongoid-to-play-niceRails Templater - Agnostic at lasthttp://feedproxy.google.com/~r/AdventuresInCoding/~3/zSwRmn8c004/rails-templater---agnostic-at-last
Mon, 31 Jan 2011 01:26:11 +0000http://adventuresincoding.com/2011/01/rails-templater---agnostic-at-last<h2>What Rails Templater used to be</h2>
<p>Rails Templater was originally a <a href="http://adventuresincoding.com/2010/07/jumpstart-your-ruby-on-rails-3-applications-with-rails-templater">Ruby on Rails 3 template</a> inspired by Mike Gunderloy’s <a href="http://github.com/ffmike/BigOldRailsTemplate">BigOldRailsTemplate</a> project. It was a very opinionated template, as it only created Rails applications using Mongoid, RSpec, jQuery, Haml, and FactoryGirl. This resulted in a large amount of forks(34 to date) by fans of the project who wanted to generate applications their way.</p>
<h2>What is Rails Templater today?</h2>
<p>The initial intentions of the template framework were small. I wanted something to generate applications the way I wanted, without all the configuration changes required after the initial generation. For example, if I wanted to use Mongoid with RSpec instead of ActiveRecord, I would have to update the RSpec configuration to take care of dropping MongoDB collections. Rails Templater takes care of all these configuration details in post bundler strategies, which take into account all the recipes chosen by the user.</p>
<p>Rails Templater is no longer just a template, but a gem providing a simple interface for generating applications. Also, the project is now completely agnostic, thus allowing you to select what you want in your application. Some examples of choices are deciding which ORM, JavaScript framework, testing framework, and fixture replacement you want to use.</p>
<h2>Usage</h2>
<p>You can give Rails Templater a try right now with the following:</p>
<div class="highlight"><pre><span class="nv">$ </span>gem install rails_templater
</pre>
</div>
<p>Once installed, generate a new Ruby on Rails 3 application using <code>templater</code></p>
<div class="highlight"><pre><span class="nv">$ </span>templater myapp
</pre>
</div>
<p>Rails Templater will ask you questions, such as which testing framework you would like to use. Once all questions are answered, a new Rails application will be generated just the way you like it.</p>
<p>Be sure to watch the screencast below to see an example of generating an app.</p>
<div class="video-container">
<iframe src="http://player.vimeo.com/video/19367709?title=0&amp;byline=0&amp;portrait=0&amp;color=ffffff" width="500" height="281" frameborder="0"></iframe></div>
<h2>Contributing new recipes</h2>
<p>If you would like to add more recipes to the project, <a href="https://github.com/kfaustino/rails-templater">fork it on GitHub</a> and send me a pull request. The current road map is to add DataMapper support and more fixture replacements, such as Fabrication.</p><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/zSwRmn8c004" height="1" width="1" alt=""/>http://adventuresincoding.com/2011/01/rails-templater---agnostic-at-lastWriting modular HTTP client code with Faradayhttp://feedproxy.google.com/~r/AdventuresInCoding/~3/jNqxY0NrRdE/writing-modular-http-client-code-with-faraday
Thu, 23 Sep 2010 00:00:00 +0000Kevin Faustinohttp://adventuresincoding.com/2010/09/writing-modular-http-client-code-with-faraday<p>What is Faraday? A natural philosopher from the 1700s? An awesome Lost character? A ruby gem by <a href="http://twitter.com/technoweenie">technoweenie</a> himself, Rick Olson? Since this blog is mostly development related, you may have concluded that this post is about the latter. <a href="http://github.com/technoweenie/faraday">Faraday</a> is an HTTP client library inspired by Rack. Requests and Responses go through middleware which allow for abstraction and modular code.</p>
<h2>Installation</h2>
<div class="highlight"><pre>gem install faraday
</pre>
</div>
<p>Be sure to also install the <a href="http://wynnnetherland.com/projects/faraday-middleware%20gem">faraday-middleware</a> by <a href="http://twitter.com/pengwynn">Wynn Netherland</a> as it provides some great middleware to consume APIs.</p>
<div class="highlight"><pre>gem install faraday-middleware
</pre>
</div>
<h2>Using Faraday</h2>
<p>To create a connection via Faraday, instantiate a new <code>Faraday::Connection</code> object with your desired options. The constructor of <code>Faraday::Connection</code> takes a block where you will define an adapter and your desired middleware.</p>
<p>An adapter represents the client library that Faraday will be utilizing to make your request. Faraday ships with the following:</p>
<ul>
<li>NetHTTP (Faraday.default_adapter)</li>
<li>Patron</li>
<li>Typhoeus</li>
<li>Test (Allows stubbing of HTTP requests)</li>
</ul>
<p><strong>Example</strong>: Creating a connection</p>
<div class="highlight"><pre><span class="n">connection</span> <span class="o">=</span> <span class="no">Faraday</span><span class="o">::</span><span class="no">Connection</span><span class="o">.</span><span class="n">new</span><span class="p">(</span>
<span class="ss">:url</span> <span class="o">=&gt;</span> <span class="s1">&#39;http://api.twitter.com/1/statuses/public_timeline.json&#39;</span><span class="p">,</span>
<span class="ss">:headers</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="ss">:accept</span> <span class="o">=&gt;</span> <span class="s1">&#39;application/json&#39;</span><span class="p">,</span>
<span class="ss">:user_agent</span> <span class="o">=&gt;</span> <span class="s1">&#39;Faraday Ruby Client&#39;</span><span class="p">})</span> <span class="k">do</span> <span class="o">|</span><span class="n">builder</span><span class="o">|</span>
<span class="n">builder</span><span class="o">.</span><span class="n">adapter</span> <span class="no">Faraday</span><span class="o">.</span><span class="n">default_adapter</span>
<span class="n">builder</span><span class="o">.</span><span class="n">use</span> <span class="no">Faraday</span><span class="o">::</span><span class="no">Response</span><span class="o">::</span><span class="no">MultiJson</span>
<span class="n">builder</span><span class="o">.</span><span class="n">use</span> <span class="no">Faraday</span><span class="o">::</span><span class="no">Response</span><span class="o">::</span><span class="no">Mashify</span>
<span class="k">end</span>
</pre>
</div>
<p>The above example represents a Faraday connection to the Twitter API public timeline method. This connection uses two middlewares from the <em>faraday-middleware</em> gem. <code>Faraday::Response::MultiJson</code> sets the body of the response to a parsed JSON response using the <a href="http://github.com/intridea/multi_json">multi_json</a> gem. Afterwards, the <code>Faraday::Response::Mashify</code> middleware uses the <a href="http://github.com/intridea/hashie">hashie</a> gem to allow dot notation on the response body instead of brackets.</p>
<p>By putting request/response operations in middleware, Faraday forces your code to follow the Single Responsibility Principle. For example, <code>Faraday::Response::MultiJson</code> is responsible for converting the JSON response into a ruby object using the best available JSON library and that alone.</p>
<p>Calling methods on the connection object will allow you to perform GET, HEAD, PUT, POST or DELETE operations.</p>
<p><strong>Example</strong>: Faraday response with MultiJson and Mashify</p>
<div class="highlight"><pre><span class="n">response</span> <span class="o">=</span> <span class="n">connection</span><span class="o">.</span><span class="n">get</span>
<span class="n">first_user</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">body</span><span class="o">.</span><span class="n">first</span><span class="o">.</span><span class="n">user</span>
<span class="nb">puts</span> <span class="n">first_user</span><span class="o">.</span><span class="n">screen_name</span>
</pre>
</div>
<h2>Creating a Middleware</h2>
<p>A common code practice when making client HTTP requests is to verify the response was successful. To abstract the response verification, move the code to Faraday response middleware. To create one, you must inherit from <code>Response::Middleware</code> and implement the methods <code>self.register_on_complete</code> and <code>initialize</code>. The interface is very similar to Rack. You can think of <code>register_on_complete(env)</code> as <code>call(env)</code> from Rack.</p>
<p><strong>Example</strong>: Twitter Error Response Middleware</p>
<div class="highlight"><pre><span class="k">module</span> <span class="nn">Faraday</span>
<span class="k">class</span> <span class="nc">Response</span><span class="o">::</span><span class="no">TwitterErrors</span> <span class="o">&lt;</span> <span class="no">Response</span><span class="o">::</span><span class="no">Middleware</span>
<span class="k">begin</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">register_on_complete</span><span class="p">(</span><span class="n">env</span><span class="p">)</span>
<span class="n">env</span><span class="o">[</span><span class="ss">:response</span><span class="o">].</span><span class="n">on_complete</span> <span class="k">do</span> <span class="o">|</span><span class="n">finished_env</span><span class="o">|</span>
<span class="k">case</span> <span class="n">finished_env</span><span class="o">[</span><span class="ss">:status</span><span class="o">]</span>
<span class="k">when</span> <span class="mi">400</span>
<span class="k">raise</span> <span class="no">Twitter</span><span class="o">::</span><span class="no">RateLimitExceeded</span><span class="p">,</span>
<span class="s2">&quot;</span><span class="si">#{</span><span class="n">finished_env</span><span class="o">[</span><span class="ss">:body</span><span class="o">][</span><span class="s1">&#39;error&#39;</span><span class="o">]</span> <span class="k">if</span> <span class="n">finished_env</span><span class="o">[</span><span class="ss">:body</span><span class="o">]</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">when</span> <span class="mi">401</span>
<span class="k">raise</span> <span class="no">Twitter</span><span class="o">::</span><span class="no">UnauthorizedError</span><span class="p">,</span>
<span class="s2">&quot;</span><span class="si">#{</span><span class="n">finished_env</span><span class="o">[</span><span class="ss">:body</span><span class="o">][</span><span class="s1">&#39;error&#39;</span><span class="o">]</span> <span class="k">if</span> <span class="n">finished_env</span><span class="o">[</span><span class="ss">:body</span><span class="o">]</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="k">when</span> <span class="mi">500</span>
<span class="k">raise</span> <span class="no">Twitter</span><span class="o">::</span><span class="no">ServerError</span><span class="p">,</span> <span class="s1">&#39;api.twitter.com is currently down&#39;</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">rescue</span> <span class="no">LoadError</span><span class="p">,</span> <span class="no">NameError</span> <span class="o">=&gt;</span> <span class="n">e</span>
<span class="nb">self</span><span class="o">.</span><span class="n">load_error</span> <span class="o">=</span> <span class="n">e</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">app</span><span class="p">)</span>
<span class="k">super</span>
<span class="vi">@parser</span> <span class="o">=</span> <span class="kp">nil</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</pre>
</div>
<h2>Note</h2>
<p>Faraday does not have gem dependencies for many of the adapters and middlewares used within it’s codebase. Ensure you have all necessary gems installed on your system.</p><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/jNqxY0NrRdE" height="1" width="1" alt=""/>http://adventuresincoding.com/2010/09/writing-modular-http-client-code-with-faraday34 Ruby on Rails 3 resources to get you startedhttp://feedproxy.google.com/~r/AdventuresInCoding/~3/_SVhrjEYZDA/34-ruby-on-rails-3-resources-to-get-you-started
Thu, 26 Aug 2010 00:00:00 +0000Kevin Faustinohttp://adventuresincoding.com/2010/08/34-ruby-on-rails-3-resources-to-get-you-started<p>With the <del>upcoming</del> final release of Ruby on Rails 3 <del>around the corner</del>, get up to speed quickly with the following 34 resources:</p>
<h2>Overviews</h2>
<p><a href="http://guides.rubyonrails.org/3_0_release_notes.html">Rails 3.0 Release Notes</a> - RailsGuides is an invaluable resource for all Ruby on Rails developers. The Rails 3 release notes provides a great overview the api changes and new features added to the framework.</p>
<p><a href="http://railsplugins.org/">RailsPlugins.org</a> – Find out if your plugins work in Rails 3.</p>
<p><a href="http://adventuresincoding.com/2010/07/having-ruby-on-rails-3-my-way/">Having Ruby on Rails 3 My Way</a> - A tutorial on how to setup Rails 3 with Mongoid, Haml, jQuery, and RSpec with Factory Girl.</p>
<p><a href="http://litanyagainstfear.com/blog/2010/02/03/the-rails-module/">The Rails Module (in Rails 3)</a> - Nick Quaranto outlines some helpful methods in the Rails module.</p>
<p><a href="http://blog.plataformatec.com.br/2010/02/rails-3-i18n-changes/">Rails 3 I18n changes</a> - A quick walkthrough the changes made to I18n.</p>
<p><a href="http://rubyonrails.org/screencasts/rails3">Ruby on Rails 3 Screencast series</a> - The official Ruby on Rails site screencast series by Gregg Pollack.</p>
<h2>ActionController / Rack</h2>
<p><a href="http://blog.plataformatec.com.br/2009/08/embracing-rest-with-mind-body-and-soul/">Embracing REST with mind, body and soul</a> - José Valim introduces RESTful responders within Rails 3 controllers.</p>
<p><a href="http://railscasts.com/episodes/224-controllers-in-rails-3">Railscasts #224 Controllers in Rails 3</a> – Ryan shows us what’s new with Rails 3 controllers.</p>
<p><a href="http://www.engineyard.com/blog/2010/render-options-in-rails-3/">Render Options in Rails 3</a> - Yehuda goes through the rendering options available in Rails 3.</p>
<p><a href="http://pivotallabs.com/users/jdean/blog/articles/1370-adding-routes-for-tests-specs-with-rails-3">Adding Routes for tests / specs with Rails 3</a> - Jeff Dean outlines how to verify routes in our specs.</p>
<p><a href="http://jasonseifer.com/2009/04/08/32-rack-resources-to-get-you-started">32 Rack Resources to Get You Started</a> - A great collection of links to get you familiar with rack.</p>
<h2>ActionMailer</h2>
<p><a href="http://lindsaar.net/2010/1/26/new-actionmailer-api-in-rails-3">New ActionMailer API in Rails 3.0</a> - Mikel Lindsaar demonstrates how to use the new ActionMailer.</p>
<p><a href="http://railsdispatch.com/posts/actionmailer">A Whole New ActionMailer</a> - Mikel Lindsaar’s Rails Dispatch post giving a tour of the ActionMailer features.</p>
<h2>ActiveRecord/ActiveModel</h2>
<p><a href="http://yehudakatz.com/2010/01/10/activemodel-make-any-ruby-object-feel-like-activerecord/">ActiveModel: Make Any Ruby Object Feel Like ActiveRecord</a> – Yehuda writes about the modularity of ActiveModel.</p>
<p><a href="http://railscasts.com/episodes/219-active-model">Railscasts #219 Active Model</a> - See how to include certain ActiveModel modules to tableless models.</p>
<p><a href="http://railsdispatch.com/posts/activerelation">ActiveRelation: ActiveRecord Gets a Facelift</a> - Carl Lerche introduces the new ActiveRecord finder api.</p>
<p><a href="http://m.onkey.org/2010/1/22/active-record-query-interface">Active Record Query Interface</a> - Pratik gives an overview of the changes made to the ActiveRecord query interface since Rails 2.</p>
<h2>Bundler</h2>
<p><a href="http://gembundler.com/">Gembundler.com</a> -The official project site for Bundler that includes extensive documentation.</p>
<p><a href="http://railsdispatch.com/posts/bundler">Library Management Gets an Update in Rails 3</a> - Andre Arko gives an overview about bundler for the Rails Dispatch blog.</p>
<p><a href="http://railscasts.com/episodes/201-bundler">Railscasts #201 Bundler</a> - A Railscasts by Ryan Bates demonstrating how to use bundler with Rails 3.</p>
<p><a href="http://adventuresincoding.com/2010/02/riding-ruby-on-rails-3-bundler/">AdventuresInCoding.com screencast on Bundler</a> – Our very first screencast from last February.</p>
<h2>Railties</h2>
<p><a href="http://www.igvita.com/2010/08/04/rails-3-internals-railtie-creating-plugins/">Rails 3 Internals: Railtie &amp; Creating Plugins</a> - Ilya Grigorik goes over Railties in Rails 3.</p>
<p><a href="http://adventuresincoding.com/2010/07/jumpstart-your-ruby-on-rails-3-applications-with-rails-templater">rails-templater</a> - A template project which generates a greenfield Rails 3 application.</p>
<p><a href="http://caffeinedd.com/guides/331-making-generators-for-rails-3-with-thor">Making generators for Rails 3 with Thor</a> – A tutorial showing you how to use the new generators and how to bundle them in a gem.</p>
<h2>Routes</h2>
<p><a href="http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/">The Lowdown on Routes in Rails 3</a> - Rizwan Reza gives us a great summary of all the different ways to create routes in Rails 3.</p>
<p><a href="http://edgeguides.rubyonrails.org/routing.html">Rails Routing from the Outside In</a> - RailsGuide documentation about the new router.</p>
<h2>Plugins</h2>
<p><a href="http://weblog.rubyonrails.org/2010/2/9/plugin-authors-toward-a-better-future">Plugin Authors: Toward a Better Future</a> - Yehuda goes through the changes for making plugins in Rails 3.</p>
<p><a href="http://railsdispatch.com/posts/building-or-updating-a-rails-3-plugin">Customizing Rails Apps with Plugins</a> - José Valim gives an overview of using responders, simple form, devise, and mail form plugins.</p>
<p><a href="http://blog.plataformatec.com.br/2010/08/devise-1-1-is-out-and-ready-to-rock-with-rails-3/">Devise 1.1 is out and ready to rock with Rails 3</a> - Outlines some new feature in Devise 1.1 including being able to authenticate a given url in the router!</p>
<h2>Books</h2>
<p><a href="http://beginningrails.com/">Beginning Rails 3</a> – Cloves Carneiro Jr and Rida Al Barazi bring us a great beginner Rails 3 book with examples viewable in gists.</p>
<p><a href="http://my.safaribooksonline.com/9780132480345">The Rails 3 Way</a> - The ultimate Ruby on Rails reference by Obie Fernandez.</p>
<p><a href="http://www.manning.com/katz/">Rails 3 In Action</a> - Ryan Bigg and Yehuda Katz deliver a great Rails book which teaches readers Rails by doing BDD with Cucumber and RSpec.</p>
<p><a href="http://www.railsupgradehandbook.com/">Rails 3 Upgrade Handbook</a> - Jeremy McAnally’s book gives you 120 pages of information about upgrading your Rails 2 application to version 3.</p>
<p><a href="http://railstutorial.org/">Ruby on Rails Tutorial: Learn Rails by Example</a> – Michael Hartl’s ebook that teaches Rails step by step.</p>
<p><strong>Update</strong>: Rails 3.0.0 was released on August 29th, 2010. To get more details, be sure to read the <a href="http://weblog.rubyonrails.org/2010/8/29/rails-3-0-it-s-done">official announcement</a>.</p><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/_SVhrjEYZDA" height="1" width="1" alt=""/>http://adventuresincoding.com/2010/08/34-ruby-on-rails-3-resources-to-get-you-startedPrototypal Inheritance in JavaScript Explainedhttp://feedproxy.google.com/~r/AdventuresInCoding/~3/_v09mQGArjo/prototypal-inheritance-in-javascript-explained
Tue, 27 Jul 2010 00:00:00 +0000Kevin Faustinohttp://adventuresincoding.com/2010/07/prototypal-inheritance-in-javascript-explained<p>One of the more advanced topics in JavaScript is how to implement inheritance in your code. The reason why inheritance causes so much confusion is because there are so many ways to implement it in JavaScript.</p>
<p>For those who are unfamiliar with inheritance, it allows us to extend a previously existing entity and supplement it by adding methods/properties to create an entirely new entity. It is an amazing way to reuse code!</p>
<p>Here is <a href="http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)">Wikipedia’s</a> definition:</p>
<blockquote>
<p>&quot;In object-oriented programming(OOP), Inheritance is a way to compartmentalize and reuse code by creating collections of attributes and behaviors called objects which can be based on previously created objects&quot;</p>
</blockquote>
<p>There are a variety of JavaScript frameworks that provide a means to perform classical inheritance. Some of these include <a href="http://www.prototypejs.org/learn/class-inheritance">Prototype</a>, <a href="http://mootools.net/docs/core/Class/Class">MooTools</a>, and <a href="http://jsclass.jcoglan.com/">ClassJS</a>. This is a great option for a team where most of the developers come from other object-oriented languages. Even though the above implementations are viable solutions, Douglas Crockford suggests the ideal solution is to use the prototypal inheritance, which has objects inheriting from other objects</p>
<h2>Implementation</h2>
<p>In JavaScript everything is an object, there is no concept of a class like other object-oriented programming languages. With prototypal inheritance, we implement inheritance by creating objects which will act as prototypes for other objects.</p>
<p>My favourite implementation comes from Stoyan Stefanov’s book <a href="http://www.amazon.com/Object-Oriented-JavaScript-high-quality-applications-libraries/dp/1847194141/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1280256010&amp;sr=8-1">Object-Oriented JavaScript: Create scalable, reusable high-quality JavaScript applications, and libraries</a>. Here is my slightly modified version of a function which abstracts the creation of a child object:</p>
<div class="highlight"><pre><span class="kd">function</span> <span class="nx">object</span><span class="p">(</span><span class="nx">parent</span><span class="p">,</span> <span class="nx">supplements</span><span class="p">){</span>
<span class="cm">/* Create a variable that will store our child object. */</span>
<span class="kd">var</span> <span class="nx">child</span><span class="p">;</span>
<span class="cm">/* Create an empty function F which will act as an intermediary between</span>
<span class="cm"> the parent and the child. F will have no properties of its own. */</span>
<span class="kd">function</span> <span class="nx">F</span><span class="p">()</span> <span class="p">{};</span>
<span class="cm">/* Assign the parent constructor to the prototype of F.</span>
<span class="cm"> This will allow the child to copy all the parentâs properties without</span>
<span class="cm"> having to set itâs prototype to the parent instance. */</span>
<span class="nx">F</span><span class="p">.</span><span class="nx">prototype</span> <span class="o">=</span> <span class="nx">parent</span><span class="p">;</span>
<span class="cm">/* Create a new child object from F. We get a copy of all the parentâs properties.</span>
<span class="cm"> Functions/objects are copied by reference. */</span>
<span class="nx">child</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">F</span><span class="p">();</span>
<span class="cm">/* Define a property uber which points to the parent object. Simulates super</span>
<span class="cm"> from other languages. */</span>
<span class="nx">child</span><span class="p">.</span><span class="nx">uber</span> <span class="o">=</span> <span class="nx">parent</span><span class="p">;</span>
<span class="cm">/* Add any functions/properties desired for the child object. */</span>
<span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="k">in</span> <span class="nx">supplements</span><span class="p">){</span>
<span class="nx">child</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">=</span> <span class="nx">supplements</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">child</span><span class="p">;</span>
<span class="p">};</span>
</pre>
</div>
<h2>Example</h2>
<p>Here is a basic example displaying how the properties are copied and overridden in a parent/child relationship.</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">parent</span> <span class="o">=</span> <span class="p">{</span>
<span class="nx">firstName</span><span class="o">:</span> <span class="s2">&quot;William&quot;</span><span class="p">,</span>
<span class="nx">lastName</span><span class="o">:</span> <span class="s2">&quot;Adama&quot;</span><span class="p">,</span>
<span class="nx">fullName</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">firstName</span> <span class="o">+</span> <span class="s2">&quot; &quot;</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">lastName</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">};</span>
<span class="kd">var</span> <span class="nx">child</span> <span class="o">=</span> <span class="nx">object</span><span class="p">(</span><span class="nx">parent</span><span class="p">,</span> <span class="p">{</span>
<span class="nx">firstName</span><span class="o">:</span> <span class="s2">&quot;Lee&quot;</span>
<span class="p">});</span>
<span class="nx">child</span><span class="p">.</span><span class="nx">fullName</span><span class="p">();</span> <span class="c1">// &quot;Lee Adama&quot;</span>
<span class="nx">parent</span><span class="p">.</span><span class="nx">fullName</span><span class="p">();</span> <span class="c1">// &quot;William Adama&quot;</span>
</pre>
</div>
<p>We can implement another version of <code>fullName()</code> that indicates William is Lee’s father without removing the parent function.</p>
<div class="highlight"><pre><span class="nx">child</span><span class="p">.</span><span class="nx">fullName</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(){</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">uber</span><span class="p">.</span><span class="nx">fullName</span><span class="p">()</span> <span class="o">+</span> <span class="s2">&quot;&#39;s child &quot;</span> <span class="o">+</span> <span class="k">this</span><span class="p">.</span><span class="nx">firstName</span><span class="p">;</span>
<span class="p">};</span>
<span class="nx">child</span><span class="p">.</span><span class="nx">fullName</span><span class="p">();</span> <span class="c1">// &quot;William Adama&#39;s child Lee&quot;</span>
<span class="nx">parent</span><span class="p">.</span><span class="nx">fullName</span><span class="p">();</span> <span class="c1">// &quot;William Adama&quot;</span>
</pre>
</div>
<p>We can even remove our child’s <code>fullName()</code> function and still have access to out parent’s function because it exists in the child’s prototype chain.</p>
<div class="highlight"><pre><span class="k">delete</span> <span class="nx">child</span><span class="p">.</span><span class="nx">fullName</span>
<span class="nx">child</span><span class="p">.</span><span class="nx">fullName</span><span class="p">();</span> <span class="c1">// &quot;Lee Adama&quot;</span>
</pre>
</div>
<h2>Benefits</h2>
<p>The benefit of using prototypal inheritance is that we are working with the strengths of JavaScript and not trying to imitate features of another language.</p>
<p>Not only does it provide an easy way to do inheritance, but there is a performance boost as well. When a function is defined in an object, they are created by reference, resulting in all child objects pointing to the same function and not creating their own copies. This can also lead to some issues if you are unaware of this. If you do not want to share any objects or functions in your child object, make sure to supplement them. Any functions/objects you create in your child object will take precedence over the parent’s version.</p>
<h2>Out in the Wild</h2>
<p>In the latest ECMAScript 5 standard, prototypal inheritance became a first class citizen as a new native method <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Object/create">Object.create(proto [, propertiesObject ])</a> was added. It allows you to create a new object with the specified prototype object and properties. You can also use it today in <a href="http://www.yuiblog.com/blog/2010/01/06/inheritance-patterns-in-yui-3/">YUI 3</a> via the Y.Object(…) function from YUI core.</p><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/_v09mQGArjo" height="1" width="1" alt=""/>http://adventuresincoding.com/2010/07/prototypal-inheritance-in-javascript-explainedHow to configure Cucumber and RSpec to work with Mongoidhttp://feedproxy.google.com/~r/AdventuresInCoding/~3/o6kXkBGUdLM/how-to-configure-cucumber-and-rspec-to-work-with-mongoid
Thu, 22 Jul 2010 00:00:00 +0000Kevin Faustinohttp://adventuresincoding.com/2010/07/how-to-configure-cucumber-and-rspec-to-work-with-mongoid<p><strong>Update</strong>: This post is outdated. An <a href="http://adventuresincoding.com/2012/05/how-to-configure-cucumber-and-rspec-to-work-with-mongoid-30">updated version</a> is available which explains how to use RSpec and Cucumber with Mongoid 3.0.</p>
<p>RSpec and Cucumber by default are setup to work with relational databases using ActiveRecord. This has been fine for the most part until so many NoSQL databases have come onto the scene. Let’s focus on getting Cucumber and RSpec working with MongoDB using Mongoid.</p>
<p>First you will need to setup your Rails 3 application to use <a href="http://adventuresincoding.com/2010/07/having-ruby-on-rails-3-my-way/">Mongoid, Cucumber, RSpec, and Factory Girl</a>. Once you have a project skeleton, you will need to setup RSpec to drop all the MongoDB collections of the project before each spec is run to ensure a clean test harness.</p>
<p>The best command to drop your MongoDB collections comes from Mongoid creator Durran Jordan in Mongoid’s <a href="http://github.com/durran/mongoid/blob/master/spec/spec_helper.rb#L32">code base</a>:</p>
<div class="highlight"><pre><span class="no">Mongoid</span><span class="o">.</span><span class="n">master</span><span class="o">.</span><span class="n">collections</span><span class="o">.</span><span class="n">select</span> <span class="p">{</span><span class="o">|</span><span class="n">c</span><span class="o">|</span> <span class="n">c</span><span class="o">.</span><span class="n">name</span> <span class="o">!~</span> <span class="sr">/system/</span> <span class="p">}</span><span class="o">.</span><span class="n">each</span><span class="p">(</span><span class="o">&amp;</span><span class="ss">:drop</span><span class="p">)</span>
</pre>
</div>
<h2>RSpec</h2>
<p>Here is a sample RSpec configuration which will empty your MongoDB db and also use Factory Girl to create your models. Note that <code>config.user_transactional_fixtures</code> is commented out.</p>
<div class="highlight"><pre><span class="c1"># spec_helper.rb</span>
<span class="no">ENV</span><span class="o">[</span><span class="s2">&quot;RAILS_ENV&quot;</span><span class="o">]</span> <span class="o">||=</span> <span class="s1">&#39;test&#39;</span>
<span class="nb">require</span> <span class="no">File</span><span class="o">.</span><span class="n">expand_path</span><span class="p">(</span><span class="s2">&quot;../../config/environment&quot;</span><span class="p">,</span> <span class="bp">__FILE__</span><span class="p">)</span>
<span class="nb">require</span> <span class="s1">&#39;rspec/rails&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;remarkable/active_model&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;remarkable/mongoid&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;factory_girl&#39;</span>
<span class="c1"># Requires supporting files with custom matchers and macros, etc,</span>
<span class="c1"># in ./support/ and its subdirectories.</span>
<span class="no">Dir</span><span class="o">[</span><span class="s2">&quot;</span><span class="si">#{</span><span class="no">File</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="bp">__FILE__</span><span class="p">)</span><span class="si">}</span><span class="s2">/support/**/*.rb&quot;</span><span class="o">].</span><span class="n">each</span> <span class="p">{</span><span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="nb">require</span> <span class="n">f</span><span class="p">}</span>
<span class="no">RSpec</span><span class="o">.</span><span class="n">configure</span> <span class="k">do</span> <span class="o">|</span><span class="n">config</span><span class="o">|</span>
<span class="n">config</span><span class="o">.</span><span class="n">mock_with</span> <span class="ss">:rspec</span>
<span class="c1"># If you&#39;re not using ActiveRecord, or you&#39;d prefer not to run each of your</span>
<span class="c1"># examples within a transaction, comment the following line or assign false</span>
<span class="c1"># instead of true.</span>
<span class="c1"># config.use_transactional_fixtures = true</span>
<span class="n">config</span><span class="o">.</span><span class="n">before</span> <span class="ss">:each</span> <span class="k">do</span>
<span class="no">Mongoid</span><span class="o">.</span><span class="n">master</span><span class="o">.</span><span class="n">collections</span><span class="o">.</span><span class="n">select</span> <span class="p">{</span><span class="o">|</span><span class="n">c</span><span class="o">|</span> <span class="n">c</span><span class="o">.</span><span class="n">name</span> <span class="o">!~</span> <span class="sr">/system/</span> <span class="p">}</span><span class="o">.</span><span class="n">each</span><span class="p">(</span><span class="o">&amp;</span><span class="ss">:drop</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
</pre>
</div>
<h2>Cucumber</h2>
<p>Cucumber allows defining hooks in any file under the <code>features/support</code> directory. To begin setting up Cucumber, first create a file <code>features/support/hooks.rb</code> that will drop your MongoDB collections before each scenario.</p>
<div class="highlight"><pre><span class="c1"># features/support/hooks.rb</span>
<span class="no">Before</span> <span class="k">do</span> <span class="o">|</span><span class="n">scenario</span><span class="o">|</span>
<span class="no">Mongoid</span><span class="o">.</span><span class="n">master</span><span class="o">.</span><span class="n">collections</span><span class="o">.</span><span class="n">select</span> <span class="p">{</span><span class="o">|</span><span class="n">c</span><span class="o">|</span> <span class="n">c</span><span class="o">.</span><span class="n">name</span> <span class="o">!~</span> <span class="sr">/system/</span> <span class="p">}</span><span class="o">.</span><span class="n">each</span><span class="p">(</span><span class="o">&amp;</span><span class="ss">:drop</span><span class="p">)</span>
<span class="k">end</span>
</pre>
</div>
<p>I also find that using Factory Girl for my Cucumber scenarios makes my life a lot easier. Below is an example features/support/env.rb file which will import all your factories. It will also provide some already defined step definitions by the guys at <a href="http://thoughtbot.com/">thoughtbot</a>. Be sure to read about them in their post <a href="http://robots.thoughtbot.com/post/284805810/gimme-three-steps">gimme three steps</a>.</p>
<div class="highlight"><pre><span class="c1"># env.rb</span>
<span class="no">ENV</span><span class="o">[</span><span class="s2">&quot;RAILS_ENV&quot;</span><span class="o">]</span> <span class="o">||=</span> <span class="s2">&quot;test&quot;</span>
<span class="nb">require</span> <span class="no">File</span><span class="o">.</span><span class="n">expand_path</span><span class="p">(</span><span class="no">File</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="bp">__FILE__</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;/../../config/environment&#39;</span><span class="p">)</span>
<span class="nb">require</span> <span class="s1">&#39;cucumber/formatter/unicode&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;cucumber/rails/rspec&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;cucumber/rails/world&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;cucumber/web/tableish&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;capybara/rails&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;capybara/cucumber&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;capybara/session&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;cucumber/rails/capybara_javascript_emulation&#39;</span>
<span class="no">Capybara</span><span class="o">.</span><span class="n">default_selector</span> <span class="o">=</span> <span class="ss">:css</span>
<span class="no">ActionController</span><span class="o">::</span><span class="no">Base</span><span class="o">.</span><span class="n">allow_rescue</span> <span class="o">=</span> <span class="kp">false</span>
<span class="nb">require</span> <span class="s1">&#39;factory_girl&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;factory_girl/step_definitions&#39;</span>
<span class="no">Dir</span><span class="o">[</span><span class="no">File</span><span class="o">.</span><span class="n">expand_path</span><span class="p">(</span><span class="no">File</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="no">File</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="bp">__FILE__</span><span class="p">),</span><span class="s1">&#39;..&#39;</span><span class="p">,</span><span class="s1">&#39;..&#39;</span><span class="p">,</span>
<span class="s1">&#39;spec&#39;</span><span class="p">,</span><span class="s1">&#39;factories&#39;</span><span class="p">,</span><span class="s1">&#39;*.rb&#39;</span><span class="p">))</span><span class="o">].</span><span class="n">each</span> <span class="p">{</span><span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="nb">require</span> <span class="n">f</span><span class="p">}</span>
</pre>
</div>
<p>All the step definitions from <code>factory_girl/step_definitions</code> work except for &quot;create record &amp; set one attribute&quot;:</p>
<div class="highlight"><pre><span class="k">Given </span><span class="nf">an author exists with an email of &quot;</span><span class="s">author@example.com</span><span class="nf">&quot;</span>
</pre>
</div>
<p>The reason for this is because in the Factory girl <a href="http://github.com/thoughtbot/factory_girl/blob/master/lib/factory_girl/step_definitions.rb#L41">code</a>, there is a check that determines if the given model responds to <code>:columns</code>. To get around this, add the following code to a new file <em>features/step_definitions/mongoid_steps.rb</em>:</p>
<div class="highlight"><pre><span class="c1"># features/step_definitions/mongoid_steps.rb</span>
<span class="no">Given</span> <span class="sr">/^an? (.+) exists with an? (.+) of &quot;([^&quot;]*)&quot;$/</span> <span class="k">do</span> <span class="o">|</span><span class="n">model</span><span class="p">,</span> <span class="n">field</span><span class="p">,</span> <span class="n">value</span><span class="o">|</span>
<span class="n">factory_name</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">gsub</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="s1">&#39;_&#39;</span><span class="p">)</span>
<span class="no">Factory</span> <span class="n">factory_name</span><span class="p">,</span> <span class="n">field</span> <span class="o">=&gt;</span> <span class="n">value</span>
<span class="k">end</span>
</pre>
</div>
<p>The last thing to do is stub out the rake task for <code>db:test:prepare</code>. The Cucumber rake tasks are still dependent on the ActiveRecord test workflow and will attempt to load the db schema into the test db. Create the file <em>lib/tasks/mongo.rake</em> to get around this:-</p>
<p><strong>Update</strong>: As of version 2.0.0.beta.14 of mongoid, a stubbed rake task for <code>db:test:clone</code> is included.</p>
<div class="highlight"><pre><span class="c1"># lib/tasks/mongo.rake</span>
<span class="n">namespace</span> <span class="ss">:db</span> <span class="k">do</span>
<span class="n">namespace</span> <span class="ss">:test</span> <span class="k">do</span>
<span class="n">task</span> <span class="ss">:prepare</span> <span class="k">do</span>
<span class="c1"># Stub out for MongoDB</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</pre>
</div>
<p>Finally, if you don’t want to do this every time you setup an application, I’ve updated <a href="http://github.com/kfaustino/rails-templater">rails-templater</a> to do the above steps automatically.</p><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/o6kXkBGUdLM" height="1" width="1" alt=""/>http://adventuresincoding.com/2010/07/how-to-configure-cucumber-and-rspec-to-work-with-mongoidJumpstart your Ruby on Rails 3 applications with rails-templaterhttp://feedproxy.google.com/~r/AdventuresInCoding/~3/-lTa8JRTLtg/jumpstart-your-ruby-on-rails-3-applications-with-rails-templater
Mon, 19 Jul 2010 06:00:00 +0000Kevin Faustinohttp://adventuresincoding.com/2010/07/jumpstart-your-ruby-on-rails-3-applications-with-rails-templater<p><strong>Update</strong>: Rails Templater is now a <a href="http://adventuresincoding.com/2011/01/rails-templater---agnostic-at-last">gem and agnostic</a>. </p>
<p>In <a href="http://adventuresincoding.com/2010/07/having-ruby-on-rails-3-my-way/">Having Ruby on Rails my way</a>, I outlined how to manually setup your Ruby on Rails 3 application to use custom generators for Mongoid, Haml, jQuery, RSpec, and factory_girl.</p>
<p>To simplify things further, I have started a template project called <a href="http://github.com/kfaustino/rails-templater">rails-templater</a>. It is inspired by Mike Gunderloy’s <a href="http://github.com/ffmike/BigOldRailsTemplate">BigOldRailsTemplate</a> project which provides templates for Rails 2.3.x projects. To get started, clone the rails-templater repository to your hard drive:</p>
<div class="highlight"><pre>% git clone http://github.com/kfaustino/rails-templater.git
</pre>
</div>
<p>When you are ready to create a new Rails 3 application, run:</p>
<div class="highlight"><pre>% rails new app_name -JOT -m <span class="se">\</span>
/path/to/rails-tempater/templater.rb
</pre>
</div>
<p>Optionally you can also use <a href="http://compass-style.org/">Compass</a> as your stylesheet framework and <a href="http://github.com/aslakhellesoy/cucumber">Cucumber</a> for integration testing.</p>
<p>I will be continuously making updates to the project by adding new recipes and template options.</p>
<p>Be sure to check out the project <a href="http://github.com/kfaustino/rails-templater">GitHub page</a>.</p>
<p>Photo credit: <a href="http://www.flickr.com/photos/dystopos/459452832/">Railroad in Crestwood</a> by dystopos</p><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/-lTa8JRTLtg" height="1" width="1" alt=""/>http://adventuresincoding.com/2010/07/jumpstart-your-ruby-on-rails-3-applications-with-rails-templaterHaving Ruby on Rails 3 my wayhttp://feedproxy.google.com/~r/AdventuresInCoding/~3/XDUkmOF7OjM/having-ruby-on-rails-3-my-way
Mon, 19 Jul 2010 00:00:00 +0000Kevin Faustinohttp://adventuresincoding.com/2010/07/having-ruby-on-rails-3-my-way<p>At RailsConf 2009, David Heinemeier Hansson during his <a href="http://railsconf.blip.tv/file/2081411/">keynote</a> mentioned that one of the central themes behind the Ruby on Rails and Merb merge was to &quot;Have it your way&quot;. Given the fact that Rails 3 is almost at a release candidate, I wanted to share my ideal Ruby on Rails setup.</p>
<p>My ideal application stack consists of Mongoid as my ODM, Haml as my template engine, jQuery as my JavaScript framework, RSpec as my testing framework, and factory_girl as my fixture replacement.</p>
<p>I will outline how to setup each of these individually for your Ruby on Rails 3 application.</p>
<p>To begin, generate a new Rails 3 application with the following command:</p>
<div class="highlight"><pre>% rails new app_name -TOJ
</pre>
</div>
<p>The flags passed into the rails command will remove certain elements from the generation of our application.</p>
<p>T – represents Test::Unit<br>
O – represents ActiveRecord<br>
J – represents Prototype</p>
<h2>Replacing ActiveRecord with Mongoid</h2>
<p><a href="http://mongoid.org/">Mongoid</a> is an Object Document Mapper for <a href="http://www.mongodb.org/">MongoDB</a>. It has a beautiful chaining criteria dsl for queries and is optimized for extremely large datasets.</p>
<p>To add mongoid to your project, add the following to your Gemfile:</p>
<div class="highlight"><pre><span class="n">gem</span> <span class="s1">&#39;mongoid&#39;</span><span class="p">,</span> <span class="s1">&#39;&gt;= 2.0.0.beta14&#39;</span>
<span class="n">gem</span> <span class="s1">&#39;bson_ext&#39;</span><span class="p">,</span> <span class="s1">&#39;1.0.4&#39;</span>
</pre>
</div>
<p>Mongoid provides a generator to setup your project to create documents for model generation and setup a sample database connection configuration. To run this generator, first execute bundle install to ensure all missing dependencies are installed. Finally, run the <code>mongoid:config</code> generator:</p>
<div class="highlight"><pre>% rails g mongoid:config
</pre>
</div>
<h2>Replacing ERB with Haml</h2>
<p><a href="http://haml-lang.com/">Haml</a> was one of the primary reasons why I feel in love with working on Ruby on Rails applications. It just makes working with markup a pleasure.</p>
<p>Adding Haml to your project requires only 1 lines in your Gemfile:</p>
<div class="highlight"><pre><span class="n">gem</span> <span class="s1">&#39;rails3-generators&#39;</span>
<span class="n">gem</span> <span class="s1">&#39;haml&#39;</span>
</pre>
</div>
<p>The gem <a href="http://github.com/indirect/rails3-generators">rails3-generators</a> provides a variety of generators for Ruby on Rails 3 applications including factory_girl which we will be using later.</p>
<p>In <code>config/application.rb</code>, add the following to your application configuration:</p>
<div class="highlight"><pre><span class="n">config</span><span class="o">.</span><span class="n">generators</span> <span class="k">do</span> <span class="o">|</span><span class="n">g</span><span class="o">|</span>
<span class="n">g</span><span class="o">.</span><span class="n">template_engine</span> <span class="ss">:haml</span>
<span class="k">end</span>
</pre>
</div>
<h2>Replacing Prototype with jQuery</h2>
<p>Using <a href="http://jquery.com/">jQuery</a> simplifies dealing with the DOM and provides all the tools necessary to do unobtrusive JavaScript in your web application. According to <a href="http://survey.hamptoncatlin.com/">Hampton Catlin&#39;s 2010 ruby survey</a>, 78.8% of all ruby users prefer it over Prototype.</p>
<p>Run the following two commands in the root of your project directory:</p>
<div class="highlight"><pre>curl -L http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js &gt; <span class="se">\</span>
public/javascripts/jquery.js
curl -L http://github.com/rails/jquery-ujs/raw/master/src/rails.js &gt; <span class="se">\</span>
public/javascripts/rails.js
</pre>
</div>
<p>Once you setup a layout file, include the two javascript files and your set.</p>
<h2>Replacing Test::Unit with RSpec</h2>
<p>With the latest beta release of <a href="http://github.com/rspec/rspec-rails">RSpec 2</a>, all generators and rake tasks are now exposed through a Railtie.</p>
<p>To replace Test::Unit as your default test framework, include the <em>rspec-rails</em> gem in both the :development and :test group in your Gemfile:</p>
<div class="highlight"><pre><span class="n">group</span> <span class="ss">:development</span><span class="p">,</span> <span class="ss">:test</span> <span class="k">do</span>
<span class="n">gem</span> <span class="s1">&#39;rspec-rails&#39;</span><span class="p">,</span> <span class="s1">&#39;&gt;= 2.0.0.beta.19&#39;</span>
<span class="k">end</span>
</pre>
</div>
<p>The next step is to install rspec into the application. The <em>rspec:install</em> generator will create a spec directory and some skeleton files. Run the following in your project root:</p>
<div class="highlight"><pre>% bundle install
% rails g rspec:install
</pre>
</div>
<p>Even though you are including RSpec as a development environment dependency, it is not completely loaded. It is only completely loaded when you invoke rails generate or rake. Read more details about this change at David Chelimsky&#39;s post <a href="http://blog.davidchelimsky.net/2010/07/11/rspec-rails-2-generators-and-rake-tasks-part-ii/">rspec-rails-2 generators and rake tasks – part II</a>.</p>
<h2>Replacing Fixtures with Factory Girl</h2>
<p>The rails3-generators gem we included earlier also provides some <a href="http://github.com/thoughtbot/factory_girl">factory_girl</a> generators. This allows for the creation of a factory when we use the model generator from Rails.</p>
<p>Add a dependency to the factory_girl_rails to the test environment in your Gemfile:</p>
<div class="highlight"><pre><span class="n">gem</span> <span class="s1">&#39;factory_girl_rails&#39;</span><span class="p">,</span> <span class="ss">:group</span> <span class="o">=&gt;</span> <span class="ss">:test</span>
</pre>
</div>
<p>You will also need to manually configure your generators to use factory_girl in <code>config/application.rb</code>. Your generators configuration should now look like the following:</p>
<div class="highlight"><pre><span class="n">config</span><span class="o">.</span><span class="n">generators</span> <span class="k">do</span> <span class="o">|</span><span class="n">g</span><span class="o">|</span>
<span class="n">g</span><span class="o">.</span><span class="n">template_engine</span> <span class="ss">:haml</span>
<span class="n">g</span><span class="o">.</span><span class="n">fixture_replacement</span> <span class="ss">:factory_girl</span><span class="p">,</span> <span class="ss">:dir</span> <span class="o">=&gt;</span> <span class="s2">&quot;spec/factories&quot;</span>
<span class="k">end</span>
</pre>
</div>
<p><strong>Update</strong>: If you absolutely love this stack, be sure to check out <a href="http://adventuresincoding.com/2010/07/jumpstart-your-ruby-on-rails-3-applications-with-rails-templater">rails-templater</a>.</p><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/XDUkmOF7OjM" height="1" width="1" alt=""/>http://adventuresincoding.com/2010/07/having-ruby-on-rails-3-my-way10 TextMate bundles/plugins to boost your Ruby on Rails development productivityhttp://feedproxy.google.com/~r/AdventuresInCoding/~3/oC8La0cjnl8/10-textmate-bundlesplugins-to-boost-your-ruby-on-rails-development-productivity
Mon, 31 May 2010 00:00:00 +0000Kevin Faustinohttp://adventuresincoding.com/2010/05/10-textmate-bundlesplugins-to-boost-your-ruby-on-rails-development-productivity<p><a href="http://macromates.com/">TextMate</a> is a widely used GUI text editor that many in the Ruby on Rails community use. The editor benefits from a large and active community of users whom develop bundles and plugins that extend TextMate’s functionality to work with a wide variety of languages and libraries.</p>
<p>Here are ten of my favourite bundles and plugins available to TextMate that will save you time and effort while working with Ruby on Rails:</p>
<p>1 - <a href="http://peepcode.com/products/peepopen">PeepOpen</a>: One of the best features of TextMate is fuzzy search(Command-T) which allows you to find files in your project with just a few characters of the filename. The issue with fuzzy search is that it becomes hard to pinpoint a file when there are many files with the same name in your project. Working in Ruby on Rails, you will face an endless amount repeated filenames in your views such as <code>index.html.erb</code>. Geoffrey Grosenbach from PeepCode, has developed an application PeepOpen that replaces the default fuzzy search with a beautiful fuzzy search that also allows you to pinpoint directories within your search. For a mere $9.00, it is a must own add-on to TextMate.</p>
<p><img src="http://media.adventuresincoding.com/images/posts/peepopen.png" alt="PeepOpen"></p>
<p>2 - <a href="http://github.com/carlosbrando/ruby-on-rails-tmbundle">Ruby on Rails</a>: Ruby on Rails development just got better with the recent changes made by Carlos Brando to <a href="http://github.com/drnic/ruby-on-rails-tmbundle">Dr. Nic’s bundle</a>. Not only does it include all the snippets and Rails integrations we are all used to, but now we also get a pseudo-intellisense for attributes for each ActiveRecord model in your project. One of my favourite additions to the bundle is the ability to easily create <a href="http://adventuresincoding.com/2010/01/taking-the-helm-of-ruby-with-ruby-version-manager/">RVM</a> <code>.rvmrc</code> files for your project. The best resource for this bundle is <a href="http://peepcode.com/products/textmate-for-rails-2">PeepCode’s TextMate for Rails 2 screencast</a>, be sure to check it out.</p>
<p>3 - <a href="http://github.com/protocool/AckMate">AckMate</a>: If you need to find some text fast, AckMate is your answer. By default, you have the power of regular expressions to pinpoint even the most complex pattern of text. AckMate also allows the filtering of files by specifying file extensions and pattern matching if a filename contains certain text.</p>
<p><img title="AckMate" src="http://media.adventuresincoding.com/images/posts/ackmate.png" width="408" height="421"></p>
<p>4 - <a href="http://github.com/subtleGradient/javascript-tools.tmbundle">JavaScript Tools</a>: JavaScript is ingrained in web development regardless of the server technology being utilized. Using the JavaScript Tools bundle you get all of the following:</p>
<ul>
<li>JavaScript Lint to check all your source code for common JavaScript mistakes</li>
<li>A JavaScript beautifier to uniform line breaks and indentation</li>
<li>Packing and minimizer tools to compress your JavaScript documents for production</li>
</ul>
<p>5 - <a href="http://github.com/kswedberg/jquery-tmbundle">JavaScript jQuery</a>: jQuery is the most popular JavaScript library available today. This bundle by jQuery team member Karl Swedberg and Jonathan Chaffer provides a huge amount of snippets to save you some keystrokes when working with jQuery.</p>
<p>6 - <a href="http://github.com/jcf/git-tmbundle">Git</a>: The Git bundle provides access to common Git commands without leaving your editor. Do things like viewing your uncommitted changes, find out who made that bad code change, and commit your changes to the repository.</p>
<p>7 &amp; 8 - <a href="http://github.com/dchelimsky/rspec-tmbundle">rSpec</a>/<a href="http://github.com/bmabey/cucumber-tmbundle">Cucumber</a>: Outside-in Rails development has never been easier with Behaviour Driven Development (BDD) tools rSpec and Cucumber. These bundles allow for the running of specs and features from within TextMate and provide an HTML output of the results.</p>
<p>9 - <a href="http://github.com/mocoso/code-beautifier.tmbundle">Code Beautifier</a>: TextMate does a good job of formatting your code but there is room for improvement. Using the Option-Command-B keyboard combination, the Code Beautifier bundle will clean up any white space and fix indentation in your ruby code. This is one of my most used bundles when I work with TextMate.</p>
<p>10 - <a href="http://github.com/grimen/compass_blueprint_tmbundle">Compass + Blueprint</a>: <a href="http://compass-style.org/">Compass</a> is the amazing Sass framework which cuts down development time by providing mixins and a means for doing unobtrusive CSS. This Compass bundle focuses on snippets for the popular Blueprint CSS framework.</p>
<p>Give these bundles/plugins a try and be sure to let me know of any you think belong on this list.</p><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/oC8La0cjnl8" height="1" width="1" alt=""/>http://adventuresincoding.com/2010/05/10-textmate-bundlesplugins-to-boost-your-ruby-on-rails-development-productivityHow to setup Git to use Diffmergehttp://feedproxy.google.com/~r/AdventuresInCoding/~3/TPDO7DR-_S4/how-to-setup-git-to-use-diffmerge
Sat, 03 Apr 2010 00:00:00 +0000Kevin Faustinohttp://adventuresincoding.com/2010/04/how-to-setup-git-to-use-diffmerge<p>Merge conflicts, they are bound to happen sooner or later when you are working in parallel with a team of developers. When Git cannot automatically merge changes, a merge fails and the conflicted file becomes littered with &lt;&lt;&lt;&lt;&lt;&lt;&lt;, =======, and &gt;&gt;&gt;&gt;&gt;&gt;&gt; markers. To ease the pain of having to performing merges, Git allows using one of many supported merge tools or you can configure Git to use the tool of your choice instead.</p>
<p>In this post, I am going to show you how to do the latter in Mac OS X using my preferred merge tool, <a href="http://www.sourcegear.com/diffmerge/index.html">Diffmerge</a>. Diffmerge is a free graphical file comparison tool by SourceGear available in Mac OS X, Linux, and Windows. It is ideal to perform 3-way merges as it supports 3-way file comparison. During a conflict, you are presented with the version of the branch you are working on, the common file ancestor, and the branch you are merging in.</p>
<h2>Visual Mergetool Configuration</h2>
<p>Running the following commands in your terminal will set Diffmerge as your default visual mergetool:</p>
<div class="highlight"><pre>git config --global merge.tool diffmerge
git config --global mergetool.diffmerge.cmd <span class="s2">&quot;diffmerge --merge</span>
<span class="s2">--result=\$MERGED \$LOCAL \$BASE \$REMOTE&quot;</span>
git config --global mergetool.diffmerge.trustExitCode <span class="nb">true</span>
</pre>
</div>
<p>As of the 3.3 release of Diffmerge, exiting a visual merge will return the correct status to Git. Prior to this release, Diffmerge would always return 0, indicating that the merge was resolved even on aborted merges. When you attempt to close Diffmerge, you will be prompted to choose if the merge is to be aborted or is resolved.</p>
<p>To start a 3-way merge with your visual mergetool, run:</p>
<div class="highlight"><pre>git mergetool
</pre>
</div>
<p>This will perform a visual merge for each file in conflict. You may also provide an optional file parameter, to perform a merge on a specific file.</p>
<h2>Don’t store backups</h2>
<p>By default, Git will store a backup of the original file with conflict markers after a successful merge. These files will have a <code>.orig</code> extension added to the original filename. When I configure Git, I ensure that these files are not saved. To globally disable backups of the original merge file, run the following:</p>
<div class="highlight"><pre>git config --global mergetool.keepBackup <span class="nb">false</span>
</pre>
</div>
<h2>Visual Difftool Configuration</h2>
<p>You may also setup Diffmerge to be your visual Difftool by running the following commands in your terminal:</p>
<div class="highlight"><pre>git config --global diff.tool diffmerge
git config --global difftool.diffmerge.cmd <span class="s2">&quot;diffmerge \$LOCAL \$REMOTE&quot;</span>
</pre>
</div>
<p>This will allow you to compare two different versions of files visually. For example:</p>
<div class="highlight"><pre>git difftool master~1 foo.rb
</pre>
</div><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/TPDO7DR-_S4" height="1" width="1" alt=""/>http://adventuresincoding.com/2010/04/how-to-setup-git-to-use-diffmergeBinged In Actionhttp://feedproxy.google.com/~r/AdventuresInCoding/~3/Jwiq2oFrNX4/binged-in-action
Sun, 21 Mar 2010 00:00:00 +0000Kevin Faustinohttp://adventuresincoding.com/2010/03/binged-in-action<p>In our <a href="http://adventuresincoding.com/2010/03/outsource-your-site-wide-search-with-binged/">last post</a>, we introduced <a href="http://github.com/kfaustino/binged">Binged</a>, a simple api wrapper for the Bing API. To demonstrate how to utilize this gem in your Ruby on Rails projects, view the screencast below:</p>
<div class="video-container">
<iframe src="http://player.vimeo.com/video/10337665?title=0&amp;byline=0&amp;portrait=0" width="500" height="281" frameborder="0"></iframe></div><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/Jwiq2oFrNX4" height="1" width="1" alt=""/>http://adventuresincoding.com/2010/03/binged-in-actionOutsource your site-wide search with Bingedhttp://feedproxy.google.com/~r/AdventuresInCoding/~3/QG6-HsfmLco/outsource-your-site-wide-search-with-binged
Mon, 15 Mar 2010 00:00:00 +0000Kevin Faustinohttp://adventuresincoding.com/2010/03/outsource-your-site-wide-search-with-binged<h2>Why use Bing for your site?</h2>
<p>The <a href="http://www.bing.com/developers">Bing API</a> does not cost you a single penny to use. It’s completely free! Bing’s biggest competitor, <a href="http://www.google.com/sitesearch/">Google Site Search</a> on the other hand can cost you from $100 annually to a price point only known by calling a google sales representative. Looking at the their small business plan, it will cost $250 annually for 1,001 – 5000 indexed pages. If your site has a lot of pages, it will start feeling very limited. Using the Bing API, you have access to the same results as the Bing search engine and not a small subset. The one limitation to the API is that you can only request the first 1000 results of a query. If your site displays 20 results per page, that is a total of 50 pages of search results.</p>
<p>Bing also provides unlimited bandwidth for queries as long as you make less than 7 queries per second per IP address. In a single day, you can query 518,400 times per server. That is a magnitude of search queries that will satisfy even large web applications. Compare this with the $750 annual google plan that only allows 500,000 queries per year!</p>
<p>Finally, the another great benefit of using the Bing API is that you can style the results to match the look and feel of your site.</p>
<h3>The Rules</h3>
<p>Based on the <a href="http://www.bing.com/developers/tou.aspx">Bing Web Services API Terms of Use</a>, the following rules must be followed in order to use Bing:</p>
<ul>
<li>It is to only be used for display in your Website or application.</li>
<li>You must display some form of attribution to Bing compliant with the Microsoft branding rules.</li>
<li>Do not filter any results you request.</li>
<li>If you interleave with other sources, you must clearly differentiate those sources.</li>
<li>Be sure to read the full Terms of Use to know exactly what you are entitled to.</li>
</ul>
<h2>Bing in Ruby via Binged</h2>
<p><a href="http://github.com/kfaustino/binged">Binged</a> is a ruby gem I wrote that wraps the Bing API. It allows ruby developers to work with bing using all the common ruby syntax and idioms they know. Binged also has a chainable query syntax to allow easy query construction based on a large set of available filters.</p>
<h3>Installation</h3>
<p><code>[sudo] gem install binged</code></p>
<h3>Get Your Bing API key</h3>
<p>To use binged, you will require a Bing API key. Create one at <a href="http://www.bing.com/developers/createapp.aspx">http://www.bing.com/developers/createapp.aspx</a>.</p>
<h2>Usage</h2>
<h3>Instantiate a Client</h3>
<div class="highlight"><pre><span class="n">binged</span> <span class="o">=</span> <span class="no">Binged</span><span class="o">::</span><span class="no">Client</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="ss">:api_key</span> <span class="o">=&gt;</span> <span class="s1">&#39;binged&#39;</span><span class="p">)</span>
</pre>
</div>
<p>The client is used to search via different sources and holds a reference to your api key to simplify calls to the API.</p>
<h3>Ruby on Rails configuration</h3>
<p>Binged allows for configuration to be done once using a configure block. To use binged in your Ruby on Rails project, configure it globally in an initializer like this:</p>
<div class="highlight"><pre><span class="c1"># config/initializers/binged.rb</span>
<span class="no">Binged</span><span class="o">.</span><span class="n">configure</span> <span class="k">do</span> <span class="o">|</span><span class="n">config</span><span class="o">|</span>
<span class="n">config</span><span class="o">.</span><span class="n">api_key</span> <span class="o">=</span> <span class="s1">&#39;api_key&#39;</span>
<span class="k">end</span>
</pre>
</div>
<p>Globally configuring Binged removes the need to provide the client with any credentials or options in your code as they would have already been set. For example, defining a client would be as follows:</p>
<div class="highlight"><pre><span class="n">binged</span> <span class="o">=</span> <span class="no">Binged</span><span class="o">::</span><span class="no">Client</span><span class="o">.</span><span class="n">new</span>
</pre>
</div>
<h3>Web Search Example</h3>
<p>The following example demonstrates how to search within a specific site for a keyword and provide a maximum of 30 results:</p>
<div class="highlight"><pre><span class="no">Binged</span><span class="o">::</span><span class="no">Client</span><span class="o">.</span><span class="n">new</span><span class="o">.</span><span class="n">web</span><span class="p">(</span><span class="s1">&#39;ruby&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">from_site</span><span class="p">(</span><span class="s1">&#39;adventuresincoding.com&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">per_page</span><span class="p">(</span><span class="mi">30</span><span class="p">)</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">result</span><span class="o">|</span>
<span class="nb">puts</span> <span class="n">result</span><span class="o">.</span><span class="n">title</span>
<span class="nb">puts</span> <span class="n">result</span><span class="o">.</span><span class="n">description</span>
<span class="nb">puts</span> <span class="n">result</span><span class="o">.</span><span class="n">url</span>
<span class="k">end</span>
</pre>
</div>
<h2>Conclusion</h2>
<p>For simple site-wide search, Bing is the optimal solution for most web applications. It is free and the usage limits are so lax, they can almost be thought of as unlimited. Be sure to check out the <a href="http://kfaustino.github.com/binged/">Binged documentation</a> to get a grasp of all the conditions you can specify in your queries. If you find a bug or have a great feature idea, <a href="http://github.com/kfaustino/binged/issues">create an issue</a> over at GitHub.</p>
<p><strong>Update</strong></p>
<p>View the <a href="http://adventuresincoding.com/2010/03/binged-in-action/">Binged screencast</a> on how to integrate Binged with your Ruby on Rails application.</p>
<p>Creative Commons: <a href="http://www.flickr.com/photos/chrisjohnbeckett/">http://www.flickr.com/photos/chrisjohnbeckett/</a> / <a href="http://creativecommons.org/licenses/by-nc-nd/2.0/">CC BY-NC-ND 2.0</a></p><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/QG6-HsfmLco" height="1" width="1" alt=""/>http://adventuresincoding.com/2010/03/outsource-your-site-wide-search-with-bingedHow to clean up your ActiveRecord migrationshttp://feedproxy.google.com/~r/AdventuresInCoding/~3/8KYbW5ebPwc/how-to-clean-up-your-activerecord-migrations
Thu, 18 Feb 2010 00:00:00 +0000Kevin Faustinohttp://adventuresincoding.com/2010/02/how-to-clean-up-your-activerecord-migrations<p>Migrations in Ruby on Rails allow you to alter your database using a convenient and easy DSL. When I started using Rails, migrations were a breath of fresh air. Database schema were finally easy. No longer did I have to pass SQL scripts to developers to run against their development DB or make a huge script to run at deployment. Migrations took care of this. However the problem with migrations is that after a while, a huge amount of migration files build up in your project. Below are detailed steps on how to clean up your migrations to make managing them easier.</p>
<h2>Step 1: Ensure you include <code>db/schema.rb</code> in your SCM</h2>
<p>The file <code>db/schema.rb</code> is the current definition of your database. It is versioned and updated after a migration is run. This file is essential in creating your database once all your older migrations are gone. Remember that <code>db/schema.rb</code> is db agnostic, so any implementation specific db statements in your migrations will not exist in the schema.</p>
<h2>Step 2: Migrate to the latest version</h2>
<p>Notify your team to checkout the latest version of your project and migrate. This will ensure that future migrations will continue to run smoothly on their current development database.</p>
<h2>Step 3: Seed your database with db/seeds.rb</h2>
<p>Go through each of your migrations and ensure that no data is being inserted in any of them. Migrations are only supposed to be used to manipulate the structure of your database, not populate it. Rails provides a file <code>db/seeds.rb</code> where you can run ruby code and model creation statements to set all the data required by your application to start.</p>
<p>Below is an example of a <code>db/seeds.rb</code> file setting up the users of a system:</p>
<div class="highlight"><pre><span class="no">User</span><span class="o">.</span><span class="n">create</span> <span class="o">[</span><span class="p">{</span> <span class="ss">:name</span> <span class="o">=&gt;</span> <span class="s1">&#39;admin&#39;</span> <span class="p">},</span> <span class="p">{</span> <span class="ss">:name</span> <span class="o">=&gt;</span> <span class="s1">&#39;foo&#39;</span> <span class="p">},</span> <span class="p">{</span> <span class="ss">:name</span> <span class="o">=&gt;</span> <span class="s1">&#39;bar&#39;</span> <span class="p">}</span><span class="o">]</span>
</pre>
</div>
<p>You can populate your database with seed data anytime by running rake db:seed. Seeding was added in Ruby on Rails 2.3.4.</p>
<h2>Step 4: Keep only latest migrations</h2>
<p>Go to <code>db/migrate</code> folder and delete all but your latest migration or move the older migrations to a folder such as <code>db/archieved_migrations</code>. You will want to keep the last migration as a reference if you need to migrate down.</p>
<h2>Step 5: Setting up a fresh environment</h2>
<p>Even though all your migrations are gone except for one, a developer can setup a fresh environment with a development database containing all required data by running one rake task: rake db:setup. This task will create the database, load the entire schema from <code>db/schema.rb</code>, and then populate the database based on <code>db/seeds.rb</code>.</p>
<p>Creative Commons:
<a href="http://www.flickr.com/photos/kaiton/">http://www.flickr.com/photos/kaiton/</a> / <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC BY-SA 2.0</a></p><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/8KYbW5ebPwc" height="1" width="1" alt=""/>http://adventuresincoding.com/2010/02/how-to-clean-up-your-activerecord-migrationsRiding Ruby on Rails 3: Bundlerhttp://feedproxy.google.com/~r/AdventuresInCoding/~3/dvFqZG2q5ac/riding-ruby-on-rails-3-bundler
Tue, 09 Feb 2010 00:00:00 +0000Kevin Faustinohttp://adventuresincoding.com/2010/02/riding-ruby-on-rails-3-bundler<p>This week a gift was given to us by the rails core team with the release of the Ruby on Rails 3 beta. To prepare both newcomers and experienced Rails developers, AdventuresInCoding is going to be releasing screencasts and posts about Ruby on Rails 3. Our first screencast is about gem dependency management with <a href="http://github.com/carlhuda/bundler">Bundler</a>.</p>
<div class="video-container">
<iframe src="http://player.vimeo.com/video/9282967?title=0&amp;byline=0&amp;portrait=0" width="500" height="281" frameborder="0"></iframe></div><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/dvFqZG2q5ac" height="1" width="1" alt=""/>http://adventuresincoding.com/2010/02/riding-ruby-on-rails-3-bundlerTaking the helm of ruby with Ruby Version Managerhttp://feedproxy.google.com/~r/AdventuresInCoding/~3/ukTqrwLisao/taking-the-helm-of-ruby-with-ruby-version-manager
Mon, 08 Feb 2010 00:00:00 +0000Kevin Faustinohttp://adventuresincoding.com/2010/02/taking-the-helm-of-ruby-with-ruby-version-manager<p><a href="http://rvm.beginrescueend.com/(RVM">Ruby Version Manager</a>) the name says it all. The sole purpose of this gem is to mange which version of ruby your system is currently utilizing. The days of creating symbolic links to different installations of ruby are over. With a single command, RVM will change the version of ruby and its gems for your entire user profile.</p>
<p>Developers using Mac OS X can start using ruby the moment they boot up their machine for the first time. In fact, the latest version of Mac OS X Snow Leopard ships with ruby 1.8.7 MRI patch level 77. The problem with system versions such as the one bundled with Mac OS X is that they stagnate, causing developers to miss out on the latest patches applied to ruby. For example. my current default version of ruby is 1.8.7 MRI patch level 248.</p>
<p>Besides the benefits of patches, why would a developer with a default version of ruby care about managing it? According to a recent report by <a href="http://railslab.newrelic.com/2010/01/07/state-of-the-stack-a-ruby-on-rails-benchmarking-report-7-january-2010">New Relic</a>, 63.5% of all deployments use ruby 1.8.6 MRI. This indicates that a large portion of the ruby community does not want to make the jump to higher version numbers. RVM provides you the tools to test, benchmark and switch your ruby versions with minimal effort. Before RVM, you would have had to compile which version of ruby you wanted, manage the symlink to it and update the PATH environment variable. If you wanted another version installed, you would have to link it to another name such as ruby19.</p>
<h2>Installing RVM</h2>
<p>Before installing RVM, make sure you have the latest Xcode developer tools installed as you will experience compilation issues with certain gems if you do not. Mongrel for example will not compile its native extensions without the latest Xcode developer tools.</p>
<p>To get started, you must first install the gem:</p>
<div class="highlight"><pre>sudo gem install rvm
</pre>
</div>
<p>Once installed, initialize the RVM installation and follow all prompts:</p>
<div class="highlight"><pre>rvm-install
</pre>
</div>
<p>Finally, install any version of ruby you would like to use, in this case the latest version of 1.8.7 MRI:</p>
<div class="highlight"><pre>rvm install 1.8.7
</pre>
</div>
<h2>Switching Between Ruby Versions</h2>
<p>To switch between versions of ruby, pass the use action to RVM:</p>
<div class="highlight"><pre>rvm use 1.9.1
rvm use 1.9.1-p378
</pre>
</div>
<p>RVM allows you to set a default version via the –default flag to easily switch to the version of ruby you use most:</p>
<div class="highlight"><pre>rvm 1.8.7 --default
rvm default
</pre>
</div>
<p>If you ever feel the need to use the original system version of ruby, RVM allows switching via the system action:</p>
<div class="highlight"><pre>rvm system
</pre>
</div>
<h2>Installing Gems</h2>
<p>All gems are installed in their own gem directory for each version of ruby. You would install gems with RVM the same way you do now, except you do not prefix sudo to the gem command. RVM runs under your user profile. By running sudo, you are telling the system to run as the root user which does not have your RVM setup.</p>
<p>Example, install the rails gem:</p>
<div class="highlight"><pre>gem install rails
</pre>
</div>
<p>RVM also allows installation of gems on multiple versions of ruby:</p>
<div class="highlight"><pre>rvm 1.8.7,1.9.1 gem install rails
</pre>
</div>
<h2>RVM Configuration</h2>
<p>To set common flags when compiling ruby gems, RVM allows settings to be placed in a <code>.rvmrc</code> file.</p>
<p>Here are the contents of my <code>~/.rvmrc</code> file:</p>
<div class="highlight"><pre><span class="nv">rvm_archflags</span><span class="o">=</span><span class="s2">&quot;-arch x86_64&quot;</span>
</pre>
</div>
<h2>MySQL Gem</h2>
<p>Some gems require flags such as the MySQL gem. To install the MySQL gem make sure you have set rvm_archflags in your .rvmrc file.</p>
<div class="highlight"><pre>gem install mysql -- --with-mysql-config<span class="o">=</span>/usr/local/mysql/bin/mysql_config
</pre>
</div>
<h2>The Benefits</h2>
<p>Besides the benefit of being able to experiment with any ruby interpreter and version, RVM has a few killer features as well. For example, RVM allows the execution of ruby programs and rake tasks across all of your ruby versions, which ensures backwards compatibility and future proofing of your ruby gems, applications, etc.</p>
<p>To run a ruby program against all installed ruby interpreters, use the ruby action:</p>
<div class="highlight"><pre>rvm ruby hello_world.rb
</pre>
</div>
<p>As with most actions, the ruby action can be restricted to a few versions:</p>
<div class="highlight"><pre>rvm ruby 1.8.7,jruby hello_word.rb
</pre>
</div>
<p>The feature I use most often is the ability to run your rake tasks across all interpreters. This is done via the rake action.</p>
<div class="highlight"><pre>rvm rake spec
</pre>
</div>
<p>Running the above command runs all of your specs across the installed interpreters. Since running your specs is a common task, RVM provides a shortcut:</p>
<div class="highlight"><pre>rvm specs
</pre>
</div>
<p>Finally, with minimal effort, RVM can help you learn how fast your code will run under each ruby version through the benchmark action.</p>
<div class="highlight"><pre>rvm benchmark hello_world.rb
</pre>
</div>
<p>Ruby Version Manager is an amazing project by <a href="http://github.com/wayneeseguin">Wayne E. Seguin</a>. It is an essential tool for gem authors and any ruby developer who has to maintain applications across multiple versions of ruby. I have been using RVM for over 6 months and it has made managing ruby a pleasure.</p><img src="//feeds.feedburner.com/~r/AdventuresInCoding/~4/ukTqrwLisao" height="1" width="1" alt=""/>http://adventuresincoding.com/2010/02/taking-the-helm-of-ruby-with-ruby-version-manager