<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>spiral_code &#187; rails</title>
	<atom:link href="http://blog.trydionel.com/tag/rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.trydionel.com</link>
	<description></description>
	<lastBuildDate>Fri, 27 Aug 2010 00:35:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Testing Sunspot with Cucumber</title>
		<link>http://blog.trydionel.com/2010/02/06/testing-sunspot-with-cucumber/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=testing-sunspot-with-cucumber</link>
		<comments>http://blog.trydionel.com/2010/02/06/testing-sunspot-with-cucumber/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 19:07:43 +0000</pubDate>
		<dc:creator>Jeff Tucker</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[pickle]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[sunspot]]></category>

		<guid isPermaLink="false">http://blog.trydionel.com/?p=124</guid>
		<description><![CDATA[I&#8217;ve been using Sunspot as my full-text search provider for a few months now. It&#8217;s a very enjoyable library &#8212; it hooks itself into Rails, provides an extension to disable itself in RSpec and even throws in a few convenient &#8230; <a href="http://blog.trydionel.com/2010/02/06/testing-sunspot-with-cucumber/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using Sunspot as my full-text search provider for <a href="http://blog.trydionel.com/2009/11/19/a-few-sunspot-tips/">a few months now</a>.  It&#8217;s a very enjoyable library &#8212; it hooks itself into Rails, provides an extension to disable itself in RSpec and even throws in a few convenient rake tasks.  This fun came to a quick end, though, when I started delving into Cucumber again.  Any feature involving finding a Sunspot-enabled item failed completely, but without any helpful errors.  After a shameful amount of time banging my head against the desk, I finally got everyone to play nicely.</p>
<h2>The Code</h2>
<p>Let&#8217;s just drop the code in and discuss it afterwards:</p>
<pre class="brush: ruby;">
# config/sunspot.yml
# copy the test settings into the cucumber environment
test: &amp;TEST
  solr:
    hostname: localhost
    port: 8981
    log_level: WARNING

cucumber:
  &lt;&lt;: *TEST

# features/support/config.rb
# start the Solr server and give it a few seconds to initialize
Sunspot::Rails::Server.start
sleep 5

# make sure that pickle calls #index! on our appropriate models
require File.join(File.dirname(__FILE__), 'pickle')
module Pickle
  module Session

    def create_model_with_sunspot(a_model_name, fields = nil)
      result = create_model_without_sunspot(a_model_name, fields)

      model = model(a_model_name)
      model.index! if model.respond_to?(:index!)

      result
    end
    alias_method_chain :create_model, :sunspot

  end
end

# clean out the Solr index after each scenario
After do
  Post.remove_all_from_index!
end

# shut down the Solr server
at_exit do
  Sunspot::Rails::Server.stop
end
</pre>
</p>
<h2>The Details</h2>
<p>This method was heavily influenced by <a href="http://opensoul.org/2009/6/1/cucumber-scenarios-that-depend-on-sphinx">Brandon Keeper&#8217;s post on using Cucumber with ThinkingSphinx</a>.  Thanks Brandon!  So in my setup, I&#8217;m using Sunspot, Cucumber and Pickle (see Ryan Bates&#8217; <a href="http://railscasts.com/episodes/186-pickle-with-cucumber">railscast on using Pickle with Cucumber</a> for more details on the wonderful Pickle gem).</p>
<p>First and foremost is getting the testing Solr server running.  It will look for settings in <code>config/sunspot.yml</code> according to the environment we&#8217;re running in, so we need to duplicate the test environment for cucumber.  I&#8217;ve found that it takes 3-5 seconds for Solr to properly spin up, so we&#8217;re <code>sleep</code>ing for a few seconds to avoid the problem.</p>
<p>Next we need to ensure that each model gets loaded into Solr&#8217;s index when created.  If you&#8217;re instantiating models on your own, this boils down to calling <code>#index!</code> on any models that you create.  Since I&#8217;m using Pickle (and didn&#8217;t want to rework the included <code>pickle_steps.rb</code>), I needed a bit more invasive measure.  A bit of <code>alias_method_chain</code> voodoo lets me call <code>#index!</code> on every instantiated model that responds to it.  This ensures that Pickle always adds it&#8217;s models to Solr&#8217;s index.  I was pleased to find that I didn&#8217;t have to disable transactional fixtures </p>
<p>Finally, we need to ensure that our index is fresh for each scenario, so we clear the Solr index out after each scenario is run.  If you want a more targeted approach, you can use</p>
<pre class="brush: ruby;">
# features/support/config.rb
# clear Solr index only if we've actually used it
After('@sunspot') do
  Post.remove_all_from_index!
end
</pre>
<p>to only clear the Solr index after stories which are tagged with <code>@sunspot</code>.  Once all the stories are run, shut down the server.  Viola!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.trydionel.com/2010/02/06/testing-sunspot-with-cucumber/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Rails Bugmash 2010</title>
		<link>http://blog.trydionel.com/2010/01/16/rails-bugmash-2010/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=rails-bugmash-2010</link>
		<comments>http://blog.trydionel.com/2010/01/16/rails-bugmash-2010/#comments</comments>
		<pubDate>Sat, 16 Jan 2010 23:47:37 +0000</pubDate>
		<dc:creator>Jeff Tucker</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[bugmash]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://blog.trydionel.com/?p=86</guid>
		<description><![CDATA[The Rails Bugmash 2010 is well under way. I&#8217;ve compiled a few notes about what I&#8217;ve seen. will_paginate The current version of the gem (v2.3.12) doesn&#8217;t work, as it relies on the now-removed scope method. It looks like there&#8217;s a &#8230; <a href="http://blog.trydionel.com/2010/01/16/rails-bugmash-2010/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The Rails Bugmash 2010 is well under way.  I&#8217;ve compiled a few notes about what I&#8217;ve seen.</p>
<h2>will_paginate</h2>
<p>The current version of the gem (v2.3.12) doesn&#8217;t work, as it relies on the now-removed <code>scope</code> method.  It looks like there&#8217;s a <a href="http://github.com/packagethief/will_paginate/commit/10e06e6451080d57a4bc914f6d9d3c21c9cffcb9">fork out there which resolves the issue</a>, but it hasn&#8217;t been merged into master yet.</p>
<h2>Formtastic</h2>
<p>The current version of the gem (v0.9.7) seems to work just fine.  All you need is an initializer to set the gem up and load it into rails:</p>
<pre class="brush: ruby;">
require 'formtastic'

# from formtastic's rails/init.rb
ActionView::Base.send :include, Formtastic::SemanticFormHelper
</pre>
<h2>validation_reflection</h2>
<p>You can use validation_reflection (v.0.3.1) with Formtastic by simply requiring it in the initializer:</p>
<pre class="brush: ruby;">
require 'formtastic'

# from formtastic's rails/init.rb
ActionView::Base.send :include, Formtastic::SemanticFormHelper

require 'validation_reflection'
</pre>
<h2>Authlogic</h2>
<p>Not sure about the working state of the gem yet, but the 2.x style generator is clearly not working.  I&#8217;ve forked <a href="http://paulbarry.com/articles/2010/01/13/customizing-generators-in-rails-3">Paul Berry&#8217;s list of Rails 3 generators</a> and <a href="http://github.com/trydionel/rails3-generators">added a simple user session generator.</a><br />
<b>Edit:</b> Actually, the gem doesn&#8217;t work either.  Seems to rely on a <code>before_persisting</code> callback which isn&#8217;t there anymore.</br><br />
<b>Edit II:</b> The <code>before_persisting</code> callback is actually built by Authlogic.  It seems the Authlogic::Session::Base module isn&#8217;t loading callbacks like it should.
</p>
<h2>RSpec</h2>
<p>This is also a no-go in Rails 3.  David Chelimsky, being the always-on-top-of-it developer, is <a href="http://blog.davidchelimsky.net/2010/01/12/rspec-2-and-rails-3/">already planning for RSpec 2.0</a> as a working partner for Rails 3.  No sign of it yet in the github repo though.  If you&#8217;re interesting in playing around anyway, you can find some RSpec generators at the link above.<br />
<h2>Bundler</h2>
<p>The new gem bundler is indeed pretty sexy.  Unfortunately, with all that great work it does, it doesn&#8217;t actually load the gems into your Rails environment.  Neither do any of the config files (boot.rb, application.rb, etc etc).  <a href="http://caffeinedd.com/guides/348-upgrading-to-rails-3">David Trasbo had some luck adding <code>Bundler.require_env</code> to the end of the environment.rb file bundler creates</a>, though he&#8217;s run into load-order troubles.  José Valim recommends placing the line at the end of application.rb to ensure the Rails core is loaded first.  This takes care of loading all the gems, so you can skip the initializers above.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.trydionel.com/2010/01/16/rails-bugmash-2010/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>A Few SunSpot Tips</title>
		<link>http://blog.trydionel.com/2009/11/19/a-few-sunspot-tips/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=a-few-sunspot-tips</link>
		<comments>http://blog.trydionel.com/2009/11/19/a-few-sunspot-tips/#comments</comments>
		<pubDate>Thu, 19 Nov 2009 15:09:37 +0000</pubDate>
		<dc:creator>Jeff Tucker</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[solr]]></category>
		<category><![CDATA[sunspot]]></category>

		<guid isPermaLink="false">http://trydionel.wordpress.com/?p=36</guid>
		<description><![CDATA[I started playing with <a href="http://github.com/outoftime/sunspot">SunSpot</a> yesterday with the intent of using it as my full-text search provider in a Rails application.  The few how-tos I found show the beautiful DSL it provides, but unfortunately not much more.  Below are a few gotchas I ran into while getting it to work on my setup. <a href="http://blog.trydionel.com/2009/11/19/a-few-sunspot-tips/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I started playing with <a href="http://github.com/outoftime/sunspot">SunSpot</a> yesterday with the intent of using it as my full-text search provider in a Rails application.  The few how-tos I found show the beautiful DSL it provides, but unfortunately not much more.  Below are a few gotchas I ran into while getting it to work on my setup.</p>
<h3>1. Sunspot includes a development version of Solr</h3>
<p>There&#8217;s no need to download an official Solr release from Apache for development work.  Just install <code>sunspot</code> and you get Solr for free, complete with some nice Rake tasks.<br />
<code><br />
gem install sunspot<br />
rake sunspot:solr:start --starts the solr server<br />
rake sunspot:solr:stop --stops the solr server<br />
</code></p>
<h3>2. Using Sunspot in Rails requires the sunspot_rails gem</h3>
<p>This one was easy to solve, but still surprised me a bit.  The <code>sunspot</code> gem only provides the base interaction with the <code>Solr</code> server.  In order to get <code>ActiveRecord</code> integration, you need to add the <a href="http://github.com/outoftime/sunspot_rails"><code>sunspot_rails</code> gem</a>:</p>
<pre class="brush: ruby;">
# config/environment.rb
config.gem 'sunspot', :lib =&amp;gt; 'sunspot'
config.gem 'sunspot_rails', :lib =&amp;gt; 'sunspot/rails'

$ rake gems:install
</pre>
<h3>3. Text Analysis is setup in Solr, not in Sunspot</h3>
<p>It seems there&#8217;s not much written in the Sunspot documentation/groups about text analysis (such as word stemming, stop word filters, synonyms analysis, etc), and for good reason.  These settings are defined in Solr&#8217;s setup via the <code>schema.xml</code> file.  More details on Solr&#8217;s text analysis abilities can be found on <a href="http://wiki.apache.org/solr/AnalyzersTokenizersTokenFilters">Apache&#8217;s website.</a>  If you&#8217;re using the install you get with Sunspot, you can find this in <code>RAILS_ROOT/solr/conf/schema.xml</code>.</p>
<h3>4. Sunspot executes its <code>search</code> DSL in a new scope</h3>
<p>This one took me forever to figure out.  By default, any details passed into Sunspot.search are not evaluated in the current context.  This means that trying to search directly from the controller just doesn&#8217;t work as I expected.  There&#8217;s no mention of this in sunspot_rails&#8217; documentation, but <a href="http://outoftime.github.com/sunspot/docs/classes/Sunspot.html#M000006">there&#8217;s a brief snippet in sunspot&#8217;s</a>:</p>
<blockquote><p>If the block passed to search takes an argument, that argument will present the DSL, and the block will be evaluated in the calling context. This will come in handy for building searches using instance data or methods</p></blockquote>
<p>So, in order to search from the controller (or rather in the model, like you should), you&#8217;ll need to pass an argument to the <code>Sunspot.search</code> block:</p>
<pre class="brush: ruby;">
@search = Sunspot.search(Post) do |query|
query.keywords params[:query]
end
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.trydionel.com/2009/11/19/a-few-sunspot-tips/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using Paperclip with Amazon S3</title>
		<link>http://blog.trydionel.com/2009/11/08/using-paperclip-with-amazon-s3/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=using-paperclip-with-amazon-s3</link>
		<comments>http://blog.trydionel.com/2009/11/08/using-paperclip-with-amazon-s3/#comments</comments>
		<pubDate>Sun, 08 Nov 2009 23:08:32 +0000</pubDate>
		<dc:creator>Jeff Tucker</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[imagemagick]]></category>
		<category><![CDATA[paperclip]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[s3]]></category>

		<guid isPermaLink="false">http://trydionel.wordpress.com/?p=21</guid>
		<description><![CDATA[I recently launched the website for my wedding on Heroku. I opted to use Thoughtbot&#8217;s popular Paperclip gem to manage photo attachments for the site. It&#8217;s a snap to use with filesystem storage (the default), but Heroku doesn&#8217;t allow applications &#8230; <a href="http://blog.trydionel.com/2009/11/08/using-paperclip-with-amazon-s3/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I recently launched the website for my wedding on Heroku. I opted to use Thoughtbot&#8217;s popular Paperclip gem to manage photo attachments for the site. It&#8217;s a snap to use with filesystem storage (the default), but Heroku doesn&#8217;t allow applications to have access to the filesystem. Plan B then is to use Paperclip&#8217;s ability to manage files over Amazon&#8217;s Simple Storage Service (aka Amazon S3).  S3 is cloud storage for ground people. It offers super cheap storage and huge bandwidth, allowing small websites to use it as a simple CDN. Initial setup is simple, albeit a bit unusual.</p>
<h3>Basic S3 Setup</h3>
<p>After registering for the service at Amazon&#8217;s site, you&#8217;ll need to collect your access credentials to allow Rails to connect to your account.  You can find this in the <a href="https://aws-portal.amazon.com/gp/aws/developer/account/index.html?ie=UTF8&amp;action=access-key">Security Credentials</a> link under the Your Account menu.  Create a simple yaml file in your <code>config</code> directory with the following details:</p>
<pre class="brush: ruby;">
# config/s3.yml
access_key_id: &amp;lt;your access key here&amp;gt;
secret_code: &amp;lt;your secret code here&amp;gt;
</pre>
<p>Note that this file can be configured to support multiple environments as well:</p>
<pre class="brush: ruby;">
# config/s3.yml
development:
  access_key_id: &amp;lt;your development access key here&amp;gt;
  secret_code: &amp;lt;your development secret code here&amp;gt;
production:
  access_key_id: &amp;lt;your production access key here&amp;gt;
  secret_code: &amp;lt;your production secret code here&amp;gt;
</pre>
<h3>S3 Buckets</h3>
<p>I found that the tricky part in setting up Paperclip was dealing with S3 buckets.  <a href="http://docs.amazonwebservices.com/AmazonS3/latest/index.html?UsingBucket.html">Buckets</a> are something like file folders in the cloud, with the unusual stipulation that each bucket name must be unique across the entire service.  Paperclip requires that you specify an S3 bucket to store your files in; unfortunately it doesn&#8217;t handle the creation of the buckets for you.  That&#8217;s where the <a href="http://amazon.rubyforge.org/">aws-s3 gem</a> comes into play.  Install it with <code>gem install aws-s3</code>, drop into the Rails console and execute the following:</p>
<pre class="brush: ruby;">
# load the aws-s3 gem
&amp;gt;&amp;gt; require 'aws/s3'
=&amp;gt; []
# connect to your account
&amp;gt;&amp;gt; AWS::S3::Base.establish_connection!(YAML.load_file('config/s3.yml').symbolize_keys!)
=&amp;gt; &amp;lt;AWS::S3::Connection:0x2236d90 @secret_access_key=&amp;lt;your secret key&amp;gt;, @http=#&amp;lt;Net::HTTP s3.amazonaws.com:80 open=false&amp;gt;, @access_key_id=&amp;lt;your access id&amp;gt;, @options={:access_key_id=&amp;gt;&amp;lt;your access id&amp;gt;, :secret_access_key=&amp;gt;&amp;lt;your secret key&amp;gt;, :server=&amp;gt;&amp;quot;s3.amazonaws.com&amp;quot;, :port=&amp;gt;80}&amp;gt;
# create your unique bucket
&amp;gt;&amp;gt; AWS::S3::Bucket.create('your_unique_s3_bucket')
=&amp;gt; true
</pre>
<h3>Paperclip with S3</h3>
<p>Once you&#8217;ve got your configuration file set and bucket created, it&#8217;s time to set up your model. <a href="http://dev.thoughtbot.com/paperclip/">Paperclip&#8217;s RDOC</a> is really great at describing all the various options for their model and is well worth the time to read through. On top of that, there are several <a href="http://patshaughnessy.net/2009/4/30/paperclip-sample-app">great tutorials</a> on getting Paperclip running. The basics though, with the important S3 bits added, look like this:</p>
<pre class="brush: ruby;">
# models/photo.rb
has_attached_file :image,
  :styles =&amp;gt; { :thumbnail =&amp;gt; &amp;quot;100x100&amp;gt;&amp;quot; },
  :storage =&amp;gt; :s3,
  :s3_credentials =&amp;gt; &amp;quot;#{Rails.root}/config/s3.yml&amp;quot;,
  :bucket =&amp;gt; &amp;quot;your_unique_s3_bucket&amp;quot;;
</pre>
<p>Note that you can specify the <code>:bucket</code> option in your <code>config/s3.yml</code> file instead.</p>
<h3>Using ImageMagick to Auto-Orient Images</h3>
<p>With the above, you&#8217;ll have a functional S3-backed Paperclip-powered model. I quickly ran into an annoying problem though. Modern digital cameras add special metadata to their photos that indicates the orientation of the camera when a photo is taken.  Unfortunately, most web browsers aren&#8217;t smart enough yet to handle that extra info, so whereas the photo appears as intended on the desktop, it appears flopped onto its side on the web. <a href="http://john.2nout.com/articles/2009/01/11/auto_rotate-post-upload-processor-for-paperclip-rails-plugin">Some developers</a> have taken to using RMagick to properly orient their photo uploads, but I&#8217;ve found that there&#8217;s a simpler way. Paperclip exposes a hook to send custom conversion flags straight to ImageMagick when a photo is uploaded. Even better, ImageMagick has a simple flag <code>-auto-orient</code> to handle automatically orient images according to their metadata. Simply change the model above to:</p>
<pre class="brush: ruby;">
# models/photo.rb
has_attached_file :image,
  :styles =&amp;gt; { :thumbnail =&amp;gt; &amp;quot;100x100&amp;gt;&amp;quot; },
  :storage =&amp;gt; :s3,
  :s3_credentials =&amp;gt; &amp;quot;#{Rails.root}/config/s3.yml&amp;quot;,
  :bucket =&amp;gt; &amp;quot;your_unique_s3_bucket&amp;quot;,
  :convert_options =&amp;gt; { :all =&amp;gt; &amp;quot;-auto-orient&amp;quot; }
</pre>
<p>You&#8217;ll now have a modern-camera-friendly, cloud-hosted image attachment system for your app.  Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.trydionel.com/2009/11/08/using-paperclip-with-amazon-s3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
