<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en-US">
  <title>Ruby, Rails, and Randomness - Home</title>
  <id>tag:naffis.com,2009:mephisto/</id>
  <generator version="0.8.0" uri="http://mephistoblog.com">Mephisto Drax</generator>
  
  <link href="http://naffis.com/" rel="alternate" type="text/html" />
  <updated>2008-10-07T16:08:15Z</updated>
  <link rel="self" href="http://feeds.feedburner.com/RubyRailsAndRandomness-Blog" type="application/atom+xml" /><entry xml:base="http://naffis.com/">
    <author>
      <name>naffis</name>
    </author>
    <id>tag:naffis.com,2008-04-03:2229</id>
    <published>2008-04-03T19:17:00Z</published>
    <updated>2008-10-07T16:08:15Z</updated>
    <category term="aws" />
    <category term="intridea" />
    <category term="press" />
    <category term="scalr" />
    <link href="http://feedproxy.google.com/~r/RubyRailsAndRandomness-Blog/~3/HJ5h1uPAcI4/intridea-s-scalr-on-techcrunch-and-aws" rel="alternate" type="text/html" />
    <title>Intridea's Scalr on TechCrunch and AWS</title>
<content type="html">
            &lt;p&gt;Since open sourcing Scalr late yesterday we've been mentioned on &lt;a href="http://www.techcrunch.com/2008/04/03/scalr-the-auto-scaling-open-source-amazon-ec2-effort/"&gt;TechCrunch&lt;/a&gt; and the &lt;a href="http://aws.typepad.com/aws/2008/04/scalr-.html"&gt;Amazon Web Services Blog&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We're extremely happy with the response so far. If anyone is interested in contributing to the project please visit the &lt;a href="http://scalr.intridea.com"&gt;Scalr Project&lt;/a&gt; on Google Code. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.techcrunch.com/2008/04/03/scalr-the-auto-scaling-open-source-amazon-ec2-effort/"&gt;&lt;img src="http://www.intridea.com/assets/2008/4/3/Picture_2.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://aws.typepad.com/aws/2008/04/scalr-.html"&gt;&lt;img src="http://www.intridea.com/assets/2008/4/3/Picture_1.png"&gt;&lt;/a&gt;&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/RubyRailsAndRandomness-Blog/~4/HJ5h1uPAcI4" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://naffis.com/2008/4/3/intridea-s-scalr-on-techcrunch-and-aws</feedburner:origLink></entry>
  <entry xml:base="http://naffis.com/">
    <author>
      <name>naffis</name>
    </author>
    <id>tag:naffis.com,2008-01-16:2112</id>
    <published>2008-01-16T16:35:00Z</published>
    <updated>2008-02-13T20:57:26Z</updated>
    <link href="http://feedproxy.google.com/~r/RubyRailsAndRandomness-Blog/~3/CjLp2GOnaJw/actsasconference" rel="alternate" type="text/html" />
    <title>ActsAsConference</title>
<content type="html">
            &lt;p&gt;Josh Owens and I will be presenting at the upcoming &lt;a href="http://www.actsasconference.com/"&gt;acts_as_conference&lt;/a&gt; February 8th and 9th in Orlando Florida. &lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.actsasconference.com/speakers/dave-naffis-josh-owens"&gt;Adding Media to Your Rails Application&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Adding media such as audio and video to a web application can be costly and time consuming. In this talk we'll cover the fundamentals and break down several solutions for uploading large files and transcoding audio and video in Rails.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.naffis.com/assets/2008/2/13/aac_adding_media.zip"&gt;Presentation slides and files&lt;/a&gt;&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/RubyRailsAndRandomness-Blog/~4/CjLp2GOnaJw" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://naffis.com/2008/1/16/actsasconference</feedburner:origLink></entry>
  <entry xml:base="http://naffis.com/">
    <author>
      <name>naffis</name>
    </author>
    <id>tag:naffis.com,2007-05-22:95</id>
    <published>2007-05-22T23:06:00Z</published>
    <updated>2007-05-22T23:14:27Z</updated>
    <category term="acts_as_viewable" />
    <category term="plugins" />
    <category term="projects" />
    <category term="rails" />
    <category term="ruby" />
    <link href="http://feedproxy.google.com/~r/RubyRailsAndRandomness-Blog/~3/Ttp3cVLzMu8/tracking-views-in-rails" rel="alternate" type="text/html" />
    <title>Tracking Views in Rails</title>
<content type="html">
            &lt;p&gt;ActsAsViewable is plugin that allows you to track page and asset views in your Rails application. For example, you can use it to track how many times a page is visited or how many times a particular image is viewed.&lt;/p&gt;


	&lt;p&gt;Trac: &lt;a href="http://trac.intridea.com/trac/public/wiki/ActsAsViewable"&gt;http://trac.intridea.com/trac/public/wiki/ActsAsViewable&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Subversion repository: &lt;a href="http://svn.intridea.com/svn/public/acts_as_viewable/"&gt;http://svn.intridea.com/svn/public/acts_as_viewable&lt;/a&gt;&lt;/p&gt;


Installation:
&lt;pre&gt;&lt;code class="ruby"&gt;script/plugin install http://svn.intridea.com/svn/public/acts_as_viewable&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;OR&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;cd vendor/plugins
svn co http://svn.intridea.com/svn/public/acts_as_viewable&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Create the tables where views will be tracked:&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;class CreateViewings &amp;lt; ActiveRecord::Migration
  def self.up
    create_table :viewings do |t|
      t.column :viewable_type,  :string
      t.column :viewable_id,    :integer
      t.column :views,          :integer,   :default =&amp;gt; 0
      t.column :created_at,     :datetime, :null =&amp;gt; false
      t.column :updated_at,     :datetime
    end
  end

  def self.down
    drop_table :viewings
  end
end&lt;/code&gt;&lt;/pre&gt;

Set the objects you want to track views for:
&lt;pre&gt;&lt;code class="ruby"&gt;class SomeAsset &amp;lt; ActiveRecord::Base
  acts_as_viewable
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Now you can increment views for these objects wherever you need to. For example in the show action of our SomeAssetController:&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;class SomeAssetController &amp;lt; ApplicationController
  def show
    @some_asset = SomeAsset.find(params[:id])
    @some_asset.increment_views
  end
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;To get the number of views:&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;@some_asset.views&lt;/code&gt;&lt;/pre&gt;
          &lt;img src="http://feeds.feedburner.com/~r/RubyRailsAndRandomness-Blog/~4/Ttp3cVLzMu8" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://naffis.com/2007/5/22/tracking-views-in-rails</feedburner:origLink></entry>
  <entry xml:base="http://naffis.com/">
    <author>
      <name>naffis</name>
    </author>
    <id>tag:naffis.com,2007-05-22:94</id>
    <published>2007-05-22T22:59:00Z</published>
    <updated>2008-09-12T15:38:22Z</updated>
    <category term="plugins" />
    <category term="projects" />
    <category term="rails" />
    <category term="ruby" />
    <category term="sessionexpiration" />
    <link href="http://feedproxy.google.com/~r/RubyRailsAndRandomness-Blog/~3/wHbDTWtE7yc/automatically-expiring-sessions-in-rails" rel="alternate" type="text/html" />
    <title>Automatically Expiring Sessions in Rails</title>
<content type="html">
            &lt;p&gt;SessionExpiration is plugin that allows you to expire sessions after X seconds of 
inactivity. Useful for when you want to automatically log out users if they’re idle.&lt;/p&gt;


	&lt;p&gt;Trac: &lt;a href="http://trac.intridea.com/trac/public"&gt;http://trac.intridea.com/trac/public&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Subversion repository: &lt;a href="http://svn.intridea.com/svn/public/session_expiration/"&gt;http://svn.intridea.com/svn/public/session_expiration/&lt;/a&gt;&lt;/p&gt;


Installation:
&lt;pre&gt;&lt;code class="ruby"&gt;script/plugin install http://svn.intridea.com/svn/public/session_expiration&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;OR&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;cd vendor/plugins
svn co http://svn.intridea.com/svn/public/session_expiration&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Specify when to expire session in your ApplicationController to do it site wide or you can do it for specific controllers:&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;class ApplicationController
  expire_session_in 5.minutes
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;If you want to run a method when the session expires use this:&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;class ApplicationController
  expire_session_in 5.minutes, :after_expiration =&amp;gt; :some_method

  def some_method
    flash[:notice] = &amp;quot;You have been logged out due to inactivity&amp;quot;
  end
end&lt;/code&gt;&lt;/pre&gt;
          &lt;img src="http://feeds.feedburner.com/~r/RubyRailsAndRandomness-Blog/~4/wHbDTWtE7yc" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://naffis.com/2007/5/22/automatically-expiring-sessions-in-rails</feedburner:origLink></entry>
  <entry xml:base="http://naffis.com/">
    <author>
      <name>dnaffis</name>
    </author>
    <id>tag:naffis.com,2006-12-11:33</id>
    <published>2006-12-11T13:38:00Z</published>
    <updated>2007-05-22T22:10:17Z</updated>
    <category term="ajax" />
    <category term="drag and drop" />
    <category term="image" />
    <category term="rails" />
    <category term="rmagick" />
    <category term="ruby" />
    <category term="sorting" />
    <category term="upload" />
    <link href="http://feedproxy.google.com/~r/RubyRailsAndRandomness-Blog/~3/8HrzD076tnA/ajax-uploads-image-manipulation-drag-and-drop-sorting" rel="alternate" type="text/html" />
    <title>Ajax uploads? Image manipulation &amp; drag-and-drop sorting.</title>
<content type="html">
            &lt;p&gt;Wouldn’t it be nice to allow uploads in a cool Ajaxy way? Well, because of security restrictions it’s just not possible. There are however ways to create the same effect.&lt;/p&gt;


	&lt;p&gt;Here’s a quick demo of an ajax-ish image upload as well as some image manipulation functionality, and drag and drop sorting. I’m not sure this will work on all browsers but it’s been tested successfully with most. This was created about 4 months ago and I never had time to polish any of it up so take what you can from it.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://www.naffis.com/demos/image_demo"&gt;http://www.naffis.com/demos/image_demo&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;First our layout (layouts/image_demo.rhtml):&lt;/strong&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code class="html"&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Strict//EN&amp;quot; &amp;quot;http://www.w3.org/TR/xhtml1/DTD/strict.dtd&amp;quot;&amp;gt;
&amp;lt;html&amp;gt;
    &amp;lt;head&amp;gt;
        &amp;lt;title&amp;gt;Image Demo&amp;lt;/title&amp;gt;
        &amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=UTF-8&amp;quot;&amp;gt;        
        &amp;lt;%= javascript_include_tag :defaults %&amp;gt;
        &amp;lt;%= stylesheet_link_tag 'image_demo' %&amp;gt;
    &amp;lt;/head&amp;gt;
    &amp;lt;body&amp;gt;
        &amp;lt;div id=&amp;quot;titlebar&amp;quot;&amp;gt;Image Demo&amp;lt;/div&amp;gt;

        &amp;lt;%= render :partial =&amp;gt; &amp;quot;upload_form&amp;quot; %&amp;gt;    

        &amp;lt;div id=&amp;quot;centercontent&amp;quot;&amp;gt;
            &amp;lt;%= yield %&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div id=&amp;quot;next&amp;quot;&amp;gt;
            &amp;lt;%= link_to &amp;quot;Create Animated Gif&amp;quot;, :action =&amp;gt; &amp;quot;animate&amp;quot; %&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div id=&amp;quot;bottom&amp;quot;&amp;gt;
            &amp;amp;copy; naffis.com 2006 
        &amp;lt;/div&amp;gt;

    &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;We’re going to extend the form_remote_tag to handle file uploads.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Drop this in your lib directory (lib/remote_uploads.rb):&lt;/strong&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;module ActionView
  module Helpers
    module PrototypeHelper
      alias_method :form_remote_tag_old, :form_remote_tag
      def form_remote_tag(options = {})
        if options[:html] &amp;amp;&amp;amp; options[:html][:multipart]      
          uid = &amp;quot;a#{Time.now.to_f.hash}&amp;quot;                                
          &amp;lt;&amp;lt;-STR    
          &amp;lt;iframe name=&amp;quot;#{uid}&amp;quot; id=&amp;quot;#{uid}&amp;quot; src=&amp;quot;about:blank&amp;quot; style=&amp;quot;position:absolute;left:-100px;width:0px;height:0px;border:0px&amp;quot;&amp;gt;&amp;lt;/iframe&amp;gt;
          &amp;lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;#{url_for options[:url].update({:iframe_remote =&amp;gt; true})}&amp;quot; enctype=&amp;quot;multipart/form-data&amp;quot; target=&amp;quot;#{uid}&amp;quot; #{%(onsubmit=&amp;quot;#{options[:loading]}&amp;quot;) if options[:loading]}&amp;gt;
          STR
        else
          form_remote_tag_old(options)
        end
      end                             
    end
  end
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&lt;strong&gt;Add the require in your environment.rb:&lt;/strong&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;require 'remote_uploads.rb'&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This will create a custom form for file uploads (multipart =&amp;gt; true) that submits to a hidden iframe. If it’s not a file upload then it will revert to the standard form_remote_tag of PrototypeHelper.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Some boring half baked styles for our demo:&lt;/strong&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code class="css"&gt;body {
  background-color:        #FFFFFF;
  background-image:        url(/maps/images/gradient.jpg);
  background-repeat:    no-repeat;
  color:                            #666666;
  font-family:                arial, sans;
  font-size:                    100%;
  line-height:                1.7em;
  margin:                            1em 2em;
}

#titlebar {
  font-size:                     1.2em;
  border-bottom:                    2px solid #333333;
  margin-bottom:                    1em;
  padding-bottom:                1em;
}

h2 {
  font-size:                     1.2em;
}

ul.navigation {
  background-color:        #333333;
  padding:                        0em 0.5em;
  list-style-type:        none;
}

ul.navigation li {
  border-right:                1px solid #666666;
  display:                        inline;
}

.navigation a {
  color:                            #FFFFFF;
  padding:                        0.5em;
}

.description {
  font-size:                    1.2em;
}

.upload {
  font-size:                    1.2em;
}

strong {
  background-color:        #FFFF99;
}

#centercontent {
  width: 100%;
  text-align: center;
  margin-bottom:                1em;
  padding-bottom:                1em;                
  margin-top:                    1em;
  padding-top:                1em;
}

#bottom {                
    width: 100%;
    float: left;
    text-align: center;
    border-top:                    2px solid #333333;
    margin-top:                    1em;
    padding-top:                1em;
}

div.float {
  width: 120px;
  padding: 10px;
  float: left;
}

div.spacer {
  clear: both;
}

div.float img {
  margin-left: 5px;
  }

div.float p {
  font-size: 9px;
  text-align: center;
  }            

#image-list ul {    
  list-style: none;
}

#image-list ul li {
  list-style: none;
  display: inline; 
    float: left;  
    width: 120px; 
    height: 120px; 
    padding: 10px;
  border: 1px solid #000;      
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;We’re using Sean Treadway’s responds_to_parent plugin (http://sean.treadway.info/svn/plugins/responds_to_parent/) to execute our &lt;span class="caps"&gt;RJS&lt;/span&gt; generated javascript in the parent window instead of the iframe which the file upload is submitted to. There are other ways of doing this that use less code but the plugin is simple so why not use it?&lt;/p&gt;


	&lt;p&gt;Everything from this point on is pretty self explanitory. I can expand on it later but here’s the rest of the code.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Our index:&lt;/strong&gt;
&lt;pre&gt;&lt;code class="html"&gt;&amp;lt;div id=&amp;quot;image-list&amp;quot;&amp;gt;
    &amp;lt;ul id=&amp;quot;sortable_list&amp;quot;&amp;gt;
        &amp;lt;% for @asset in @assets %&amp;gt;
            &amp;lt;%= render :partial =&amp;gt; &amp;quot;image_container&amp;quot;, :locals =&amp;gt; { :asset =&amp;gt; @asset } %&amp;gt;
        &amp;lt;% end %&amp;gt;
    &amp;lt;/ul&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;%= sortable_element('sortable_list', :constraint =&amp;gt; false, :url =&amp;gt; {:action =&amp;gt; :update_positions}) %&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;


	&lt;p&gt;Some partials used above:&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;_image_container.rhtml&lt;/strong&gt;
&lt;pre&gt;&lt;code class="html"&gt;&amp;lt;li id=&amp;quot;item_&amp;lt;%= @asset.id %&amp;gt;&amp;quot; class=&amp;quot;float&amp;quot;&amp;gt;
    &amp;lt;%= render :partial =&amp;gt; &amp;quot;image_thumb&amp;quot;, :locals =&amp;gt; { :asset =&amp;gt; @asset } %&amp;gt;
&amp;lt;/li&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;_image_thumb.rhtml&lt;/strong&gt;
&lt;pre&gt;&lt;code class="html"&gt;&amp;lt;%= image_tag @asset.thumbnail, :border =&amp;gt; 2 %&amp;gt;
    &amp;lt;br&amp;gt;
    &amp;lt;%= link_to_remote(image_tag(&amp;quot;arrow_rotate_anticlockwise.png&amp;quot;, :border =&amp;gt; 0), :url =&amp;gt; {:action =&amp;gt; &amp;quot;rotate&amp;quot;, :id =&amp;gt; @asset.id, :direction =&amp;gt; &amp;quot;left&amp;quot;} ) %&amp;gt;
    &amp;amp;nbsp;
    &amp;lt;%= link_to_remote(image_tag(&amp;quot;cross.png&amp;quot;, :border =&amp;gt; 0), :url =&amp;gt; {:action =&amp;gt; &amp;quot;remove&amp;quot;, :id =&amp;gt; @asset.id} ) %&amp;gt;
    &amp;amp;nbsp;
    &amp;lt;%= link_to_remote(image_tag(&amp;quot;arrow_rotate_clockwise.png&amp;quot;, :border =&amp;gt; 0), :url =&amp;gt; {:action =&amp;gt; &amp;quot;rotate&amp;quot;, :id =&amp;gt; @asset.id, :direction =&amp;gt; &amp;quot;right&amp;quot;} ) %&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;_upload_form.rhtml&lt;/strong&gt;
&lt;pre&gt;&lt;code class="html"&gt;&amp;lt;%= form_remote_tag(:url =&amp;gt; { 
        :controller =&amp;gt; &amp;quot;image_demo&amp;quot;, 
        :action =&amp;gt; &amp;quot;create&amp;quot; },             
        :html =&amp;gt; {:multipart =&amp;gt; true}) %&amp;gt;
    &amp;lt;b&amp;gt;Picture:&amp;lt;/b&amp;gt;&amp;amp;nbsp;
    &amp;lt;%= file_field_tag &amp;quot;asset&amp;quot; %&amp;gt;&amp;amp;nbsp;
    &amp;lt;%= submit_tag &amp;quot;Upload&amp;quot; %&amp;gt;&amp;amp;nbsp;
&amp;lt;%= end_form_tag %&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;


	&lt;p&gt;Our &lt;span class="caps"&gt;RJS&lt;/span&gt; to handle the create, remove, and rotate.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;create.rjs&lt;/strong&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;if @asset.new_record?
  page.alert &amp;quot;There was a problem uploading your file:\n&amp;quot; +
  @asset.errors.full_messages.join(&amp;quot;\n&amp;quot;)
else
  page.insert_html :top, 'sortable_list', :partial =&amp;gt; 'image_container', :locals =&amp;gt; { :asset =&amp;gt; @asset } 
  page.visual_effect :highlight, &amp;quot;item_#{@asset.id}&amp;quot;
  page.sortable &amp;quot;sortable_list&amp;quot;, :constraint =&amp;gt; false, :url =&amp;gt; { :action =&amp;gt; :update_positions }
end&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;remove.rjs&lt;/strong&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;page.remove &amp;quot;item_#{@asset_id}&amp;quot;
page.sortable &amp;quot;sortable_list&amp;quot;, :constraint =&amp;gt; false, :url =&amp;gt; { :action =&amp;gt; :update_positions }&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;rotate.rjs&lt;/strong&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;page.replace_html &amp;quot;item_#{@asset.id}&amp;quot;, :partial =&amp;gt; 'image_thumb', :locals =&amp;gt; { :asset =&amp;gt; @asset } 
page.visual_effect :highlight, &amp;quot;item_#{@asset.id}&amp;quot;
page.sortable &amp;quot;sortable_list&amp;quot;, :constraint =&amp;gt; false, :url =&amp;gt; { :action =&amp;gt; :update_positions }&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Our controller:&lt;/strong&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class ImageDemoController &amp;lt; ApplicationController 
  layout 'image_demo'

  def index
    session[:uid] = Time.now.to_i unless session[:uid]      
    @assets = Asset.find(:all, 
                         :conditions =&amp;gt; [&amp;quot;user_id = ?&amp;quot;, session[:uid].to_i],
    :order =&amp;gt; &amp;quot;position&amp;quot;)    
  end

  def create
    @asset = Asset.new()
    @asset.uploaded_file = params['asset']
    @asset.position = 0
    @asset.user_id = session[:uid].to_i
    @asset.save    
    responds_to_parent do
      render :action =&amp;gt; 'create.rjs'
    end
    return
  end    

  def list
    @assets = Asset.find(:all, 
                         :conditions =&amp;gt; [&amp;quot;user_id = ?&amp;quot;, session[:uid].to_i],
    :order =&amp;gt; &amp;quot;position&amp;quot;)
  end  

  def update_positions
    params[:sortable_list].each_with_index do |id, position|
      Asset.update(id, :position =&amp;gt; position)
    end
    render :nothing =&amp;gt; true
  end

  def rotate
    @asset = Asset.find(params[:id])
    degrees = params[:direction] == &amp;quot;left&amp;quot; ? -90 : 90
    @asset.rotate(degrees)
  end

  def remove
    @asset_id = params[:id]
    Asset.delete(@asset_id)
  end

end&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Our asset model:&lt;/strong&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;require 'RMagick'

class Asset &amp;lt; ActiveRecord::Base 

  def uploaded_file=(incoming_file)
    content_type = incoming_file.content_type.chomp
    if content_type.rindex(/image\/[(jpe?g)||(gif)]/)
      self.name = base_part_of(incoming_file.original_filename)

      base_dir = &amp;quot;/some/path/you/like&amp;quot;           

      # save original file
      self.original = &amp;quot;image_demo_assets/o_#{Time.now.utc.to_i}#{rand(1000000)}.&amp;quot;+self.name
      File.open(base_dir+self.original,File::CREAT|File::TRUNC|File::WRONLY,0666){ |f|
        f.write(incoming_file.read)
      }      

      self.resized = &amp;quot;image_demo_assets/r_#{Time.now.utc.to_i}#{rand(1000000)}.&amp;quot;+self.name
      resized = Magick::Image.read(base_dir+self.original).first
      resized.change_geometry!('500x500') { |cols, rows, img|
        img.resize!(cols, rows)
      }
      resized.write(base_dir+self.resized) 

      self.thumbnail = &amp;quot;image_demo_assets/t_#{Time.now.utc.to_i}#{rand(1000000)}.&amp;quot;+self.name        
      thumb = Magick::Image.read(base_dir+self.original).first
      thumb.change_geometry!('100x100') { |cols, rows, img|
        img.resize!(cols, rows)
      }
      thumb.write(base_dir+self.thumbnail)     

      self.save    
    end
  end

  def rotate(degrees) 
    base_dir = &amp;quot;/some/path/you/like&amp;quot;       
    #main photo
    image = Magick::ImageList.new(base_dir+self.original)
    image = image.rotate(degrees)
    image.write(base_dir+self.original)

    # resized
    resized = Magick::ImageList.new(base_dir+self.resized)
    resized = resized.rotate(degrees)
    resized.write(base_dir+self.resized)    

    # thumb
    thumb = Magick::ImageList.new(base_dir+self.thumbnail)
    thumb = thumb.rotate(degrees)
    thumb.write(base_dir+self.thumbnail)    
  end

  private

  def base_part_of(file_name)
    name = File.basename(file_name)
    name.gsub(/[^W._-]/, '')
    sanitize_filename(name)
  end

  # Fixes a 'feature' of IE where it passes the entire path instead of just the filename
  def sanitize_filename(value)
    #get only the filename (not the whole path)
    just_filename = value.gsub(/^.*(\\|\/)/, '')
    just_filename.gsub(/[^\w\.\-]/,'_') 
  end

end&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;


Some suggestions:
&lt;ul&gt;
&lt;li&gt;Use form_for and get rid of some ugliness in the controller by using Asset.new(params[:asset]) instead of setting each value individually.&lt;/li&gt;
&lt;li&gt;Use simply_helpful for generiting your &lt;span class="caps"&gt;DOM&lt;/span&gt; id’s.&lt;/li&gt;
&lt;li&gt;Use acts_as_attachment for handing the storing of files. &lt;/li&gt;
&lt;li&gt;Better validations (aaa will handle that too).&lt;/li&gt;
&lt;li&gt;Rewrite the whole thing.&lt;/li&gt;
&lt;/ul&gt;

	&lt;p&gt;Again, this is a &lt;span class="caps"&gt;VERY&lt;/span&gt; quick-and-dirty demo written in about 20 minutes with so much room for improvement. If I had the time I would, but alas I hope it helps.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/RubyRailsAndRandomness-Blog/~4/8HrzD076tnA" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://naffis.com/2006/12/11/ajax-uploads-image-manipulation-drag-and-drop-sorting</feedburner:origLink></entry>
  <entry xml:base="http://naffis.com/">
    <author>
      <name>dnaffis</name>
    </author>
    <id>tag:naffis.com,2006-10-22:32</id>
    <published>2006-10-22T01:20:00Z</published>
    <updated>2007-05-22T22:21:36Z</updated>
    <link href="http://feedproxy.google.com/~r/RubyRailsAndRandomness-Blog/~3/l1j-Zn4E82I/neglecting-my-blog" rel="alternate" type="text/html" />
    <title>Neglecting my blog</title>
<content type="html">
            &lt;p&gt;So yeah I’ve been neglecting my blog. I’ve been working way too many hours recently and haven’t had a moment to post anything. I have about 20 or so posts to make, a few code samples, and some plugins I’ll hopefully get around to releasing this weekend.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/RubyRailsAndRandomness-Blog/~4/l1j-Zn4E82I" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://naffis.com/2006/10/22/neglecting-my-blog</feedburner:origLink></entry>
  <entry xml:base="http://naffis.com/">
    <author>
      <name>dnaffis</name>
    </author>
    <id>tag:naffis.com,2006-10-22:31</id>
    <published>2006-10-22T01:18:00Z</published>
    <updated>2007-05-22T22:19:23Z</updated>
    <category term="has_many" />
    <category term="patch" />
    <category term="rails" />
    <category term="ruby" />
    <link href="http://feedproxy.google.com/~r/RubyRailsAndRandomness-Blog/~3/mVScbpc_B8U/problem-with-has_many-through" rel="alternate" type="text/html" />
    <title>Problem with has_many :through</title>
<content type="html">
            &lt;p&gt;I recently ran into a problem using has_many :through relationships. The edge code works fine when using standard id’s but for those using legacy databases or non-standard id’s in your join table the code fails when trying to add or delete an association.&lt;/p&gt;


	&lt;p&gt;Something like this would fail:&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;create_table :books, :force =&amp;gt; true do |t|
  t.column :name, :string
end

create_table :citations, :id =&amp;gt; false, :force =&amp;gt; true do |t|
  t.column :book1_id, :integer
  t.column :book2_id, :integer
end

class Book &amp;lt; ActiveRecord::Base
  has_many :citations, :foreign_key =&amp;gt; 'book1_id'  
  has_many :references, :through =&amp;gt; :citations, :source =&amp;gt; :reference_of, :uniq =&amp;gt; true
end

class Citation &amp;lt; ActiveRecord::Base
  belongs_to :reference_of, :class_name =&amp;gt; &amp;quot;Book&amp;quot;, :foreign_key =&amp;gt; :book2_id 
  belongs_to :book1, :class_name =&amp;gt; &amp;quot;Book&amp;quot;, :foreign_key =&amp;gt; :book1_id 
  belongs_to :book2, :class_name =&amp;gt; &amp;quot;Book&amp;quot;, :foreign_key =&amp;gt; :book2_id 
end

awdr = Book.create!(:name =&amp;gt; &amp;quot;Agile Web Development with Rails&amp;quot;)
rfr = Book.create!(:name =&amp;gt; &amp;quot;Ruby for Rails&amp;quot;)

awdr.references &amp;lt;&amp;lt; rfr
awdr.delete(rfr)&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;There’s further information at &lt;a href="http://dev.rubyonrails.org/ticket/6466"&gt;http://dev.rubyonrails.org/ticket/6466&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;If you’re running into this problem you can patch your local version of rails. First freeze edge in your tree. Then create the file has_many_through_patch.rb in your lib directory with the following code:&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;module ActiveRecord

  class HasManyThroughCantDisassociateNewRecords &amp;lt; ActiveRecordError #:nodoc:
    def initialize(owner, reflection)
      super(&amp;quot;Cannot disassociate new records through '#{owner.class.name}##{reflection.name}' on '#{reflection.source_reflection.class_name rescue nil}##{reflection.source_reflection.name rescue nil}'. Both records must have an id in order to delete the has_many :through record associating them.&amp;quot;)
    end
  end

  module Associations
    class HasManyThroughAssociation

      # Construct attributes for :through pointing to owner and associate.
      def construct_join_attributes(associate)
        construct_owner_attributes(@reflection.through_reflection).merge(@reflection.source_reflection.primary_key_name =&amp;gt; associate.id)
      end

      # Remove +records+ from this association.  Does not destroy +records+.
      def delete(*records)
         return if records.empty?
         records.each { |associate| raise_on_type_mismatch(associate) }
         through = @reflection.through_reflection
         raise ActiveRecord::HasManyThroughCantDisassociateNewRecords.new(@owner, through) if @owner.new_record?

         load_target

         klass = through.klass
         klass.transaction do
           flatten_deeper(records).each do |associate|
             raise_on_type_mismatch(associate)
             raise ActiveRecord::HasManyThroughCantDisassociateNewRecords.new(@owner, through) unless associate.respond_to?(:new_record?) &amp;amp;&amp;amp; !associate.new_record?

             @owner.send(@reflection.through_reflection.name).proxy_target.delete(klass.delete_all(construct_join_attributes(associate)))
             @target.delete(associate)
           end
         end

         self  
       end
    end
  end
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Then in your environment.rb add the following:&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;require 'has_many_through_patch'&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;You should be able to add and delete now until the patch is committed.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/RubyRailsAndRandomness-Blog/~4/mVScbpc_B8U" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://naffis.com/2006/10/22/problem-with-has_many-through</feedburner:origLink></entry>
  <entry xml:base="http://naffis.com/">
    <author>
      <name>dnaffis</name>
    </author>
    <id>tag:naffis.com,2006-08-31:30</id>
    <published>2006-08-31T22:29:00Z</published>
    <updated>2008-04-15T20:20:24Z</updated>
    <category term="ajax" />
    <category term="css" />
    <category term="rails" />
    <category term="ruby" />
    <category term="star rating" />
    <category term="star rating system" />
    <link href="http://feedproxy.google.com/~r/RubyRailsAndRandomness-Blog/~3/8udJr1yfMfY/rails-ajax-star-rating-system" rel="alternate" type="text/html" />
    <title>Ruby on Rails, Ajax &amp; CSS Star Rating System</title>
<content type="html">
            &lt;p&gt;I’m sure everyone by now has seen those oh-so-Web 2.0 star rating features on hundreds of websites. Well I needed to implement one for a site I’m working on and I couldn’t find a complete example anywhere (not in RoR). So here it is. A complete Rails based Ajax and &lt;span class="caps"&gt;CSS&lt;/span&gt; star ratings sytem with some &lt;span class="caps"&gt;RJS&lt;/span&gt; thrown in for good measure.&lt;/p&gt;


	&lt;p&gt;I used Rogie’s very elegant &lt;span class="caps"&gt;CSS&lt;/span&gt; only star rating system found here &lt;a href="http://komodomedia.com/blog/index.php/2006/01/09/css-star-rating-part-deux/"&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt; Star Rating Part Deux&lt;/a&gt;. I also used Chris Ingrassia’s &lt;a href="http://rubyforge.org/projects/rateableplugin/"&gt;acts_as_rateable plugin&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;So here we go.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Get the &lt;span class="caps"&gt;CSS&lt;/span&gt; and change the image url’s&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;First figure out which version of the &lt;span class="caps"&gt;CSS&lt;/span&gt; ratings you like. I used this &lt;a href="http://komodomedia.com/blog/samples/star_rating/example1.htm"&gt;example&lt;/a&gt;.&lt;/p&gt;


&lt;pre&gt;&lt;code class="css"&gt;/*             styles for the star rater                */    
    .star-rating{
        list-style:none;
        margin: 0px;
        padding:0px;
        width: 150px;
        height: 30px;
        position: relative;
        background: url(/images/star_rating.gif) top left repeat-x;        
    }
    .star-rating li{
        padding:0px;
        margin:0px;
        /*\*/
        float: left;
        /* */
    }
    .star-rating li a{
        display:block;
        width:30px;
        height: 30px;
        text-decoration: none;
        text-indent: -9000px;
        z-index: 20;
        position: absolute;
        padding: 0px;
    }
    .star-rating li a:hover{
        background: url(/images/star_rating.gif) left center;
        z-index: 2;
        left: 0px;
        border:none;
    }
    .star-rating a.one-star{
        left: 0px;
    }
    .star-rating a.one-star:hover{
        width:30px;
    }
    .star-rating a.two-stars{
        left:30px;
    }
    .star-rating a.two-stars:hover{
        width: 60px;
    }
    .star-rating a.three-stars{
        left: 60px;
    }
    .star-rating a.three-stars:hover{
        width: 90px;
    }
    .star-rating a.four-stars{
        left: 90px;
    }    
    .star-rating a.four-stars:hover{
        width: 120px;
    }
    .star-rating a.five-stars{
        left: 120px;
    }
    .star-rating a.five-stars:hover{
        width: 150px;
    }
    .star-rating li.current-rating{
        background: url(/images/star_rating.gif) left bottom;
        position: absolute;
        height: 30px;
        display: block;
        text-indent: -9000px;
        z-index: 1;
    }&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&lt;i&gt;Make sure you change your image url’s so that your Rails app can find them.&lt;/i&gt;&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Get the images for your &lt;span class="caps"&gt;CSS&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Grab the images used in your &lt;span class="caps"&gt;CSS&lt;/span&gt; and put them in your images directory. Here are both&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://komodomedia.com/blog/samples/star_rating/star_rating.gif"&gt;  &lt;img src="http://komodomedia.com/blog/samples/star_rating/alt_star.gif"&gt;.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Install the acts_as_rateable plugin. &lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Run the following from the root of your Rails app to install the plugin.&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;script/plugin install http://juixe.com/svn/acts_as_rateable&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&lt;strong&gt;Create the tables used by acts_as_rateable&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Create a file &lt;i&gt;db/migrate/xxx_create_ratings.rb&lt;/i&gt; (xxx is 001 if it’s the first migration file you have).&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;class CreateRatings&amp;lt; ActiveRecord::Migration

  def self.up
    create_table :ratings, :force =&amp;gt; true do |t|
      t.column :rating, :integer, :default =&amp;gt; 0
      t.column :created_at, :datetime, :null =&amp;gt; false
      t.column :rateable_type, :string, :limit =&amp;gt; 15,
      :default =&amp;gt; &amp;quot;&amp;quot;, :null =&amp;gt; false
      t.column :rateable_id, :integer, :default =&amp;gt; 0, :null =&amp;gt; false
      t.column :user_id, :integer, :default =&amp;gt; 0, :null =&amp;gt; false
    end

    add_index :ratings, [&amp;quot;user_id&amp;quot;], :name =&amp;gt; &amp;quot;fk_ratings_user&amp;quot;
  end

  def self.down
    drop_table :ratings
  end

end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Run your migration.&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;rake migrate&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;You should now have the appropriate tables.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Make one of your models rateable&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;I was trying to add a rating system for the model Asset. Yours can obviously be whatever you like but from here on out I’ll be using Asset. So add acts_as_rateable to your model.&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;class Asset &amp;lt; ActiveRecord::Base
  acts_as_rateable
  ...
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&lt;strong&gt;Create a controller to handle the rating submissions&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Create the file /controllers/rating_controller.rb&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;class RatingController &amp;lt; ApplicationController

  def rate
    @asset = Asset.find(params[:id])
    Rating.delete_all([&amp;quot;rateable_type = 'Asset' AND rateable_id = ? AND user_id = ?&amp;quot;, 
      @asset.id, current_user.id])
    @asset.add_rating Rating.new(:rating =&amp;gt; params[:rating], 
      :user_id =&amp;gt; current_user.id)
  end

end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Two things to note here. First I’m associating ratings to users. I’ve already implemented a user/permission system for my site using the model User. Use whatever is appropriate for you. You can modify this whole example to work without associating ratings to users, the acts_as_rateable plugin will handle it just fine. However, I’m not going to get into that here.&lt;/p&gt;


	&lt;p&gt;Since I am associating ratings to users it would be bad to have a user skew the results by storing multiple ratings for a single Asset. Hence the delete. I’m telling it to delete all ratings for the rateable_type ‘Asset’ and the id (rateable_id) of the Asset. The rateable_type of Asset is handled by the plugin and stored in the ratings table.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Create your views&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Create the partial &lt;i&gt;/views/rating/_rating.rhtml&lt;/i&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code class="html"&gt;&amp;lt;%= number_with_precision(asset.rating, 1) %&amp;gt;/5 Stars&amp;lt;br&amp;gt;
&amp;lt;ul class='star-rating'&amp;gt;
    &amp;lt;li class='current-rating' style='width:&amp;lt;%= (asset.rating * 30).to_i -%&amp;gt;px;'&amp;gt;
          Currently &amp;lt;%= number_with_precision(asset.rating, 1) %&amp;gt;/5 Stars.
        &amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;
        &amp;lt;%= link_to_remote( &amp;quot;1&amp;quot;, {:url =&amp;gt; { :controller =&amp;gt; &amp;quot;rating_demo&amp;quot;, 
            :action =&amp;gt; &amp;quot;rate&amp;quot;, :id =&amp;gt; asset.id, :rating =&amp;gt; 1}},
            :class =&amp;gt; 'one-star', :name =&amp;gt; '1 star out of 5') %&amp;gt;
    &amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;
        &amp;lt;%= link_to_remote( &amp;quot;2&amp;quot;, {:url =&amp;gt; { :controller =&amp;gt; &amp;quot;rating_demo&amp;quot;, 
            :action =&amp;gt; &amp;quot;rate&amp;quot;, :id =&amp;gt; asset.id, :rating =&amp;gt; 2}},
            :class =&amp;gt; 'two-stars', :name =&amp;gt; '2 stars out of 5') %&amp;gt;    
    &amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;
        &amp;lt;%= link_to_remote( &amp;quot;3&amp;quot;, {:url =&amp;gt; { :controller =&amp;gt; &amp;quot;rating_demo&amp;quot;, 
            :action =&amp;gt; &amp;quot;rate&amp;quot;, :id =&amp;gt; asset.id, :rating =&amp;gt; 3}},
            :class =&amp;gt; 'three-stars', :name =&amp;gt; '3 stars out of 5') %&amp;gt;
    &amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;
        &amp;lt;%= link_to_remote( &amp;quot;4&amp;quot;, {:url =&amp;gt; { :controller =&amp;gt; &amp;quot;rating_demo&amp;quot;, 
            :action =&amp;gt; &amp;quot;rate&amp;quot;, :id =&amp;gt; asset.id, :rating =&amp;gt; 4}},
            :class =&amp;gt; 'four-stars', :name =&amp;gt; '4 stars out of 5') %&amp;gt;    
    &amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;
        &amp;lt;%= link_to_remote( &amp;quot;5&amp;quot;, {:url =&amp;gt; { :controller =&amp;gt; &amp;quot;rating_demo&amp;quot;, 
            :action =&amp;gt; &amp;quot;rate&amp;quot;, :id =&amp;gt; asset.id, :rating =&amp;gt; 5}},
            :class =&amp;gt; 'five-stars', :name =&amp;gt; '5 stars out of 5') %&amp;gt;
    &amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Obviously it’s using Ajax with the prototype helper link_to_remote to submit the user’s rating. One thing to note. Where you see width:&amp;lt;&lt;span&gt;= (asset.rating * 30).to_i  -&lt;/span&gt;&amp;gt;px;’ you’ll have to modify this to correspond with the images you chose to use. The one I’m using has images which are 30px wide. If you chose the smaller star images then you’ll have to modify this calculation to correspond to your image width. By the way, this is the line that handles the display of the current rating.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;And now a little &lt;span class="caps"&gt;RJS&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Create the file &lt;i&gt;/views/rating/rate.rjs&lt;/i&gt;&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;page.replace_html &amp;quot;star-ratings-block&amp;quot;, :partial =&amp;gt; 'rating/rating', :locals =&amp;gt; { :asset =&amp;gt; @asset }&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This will replace the star ratings with the partial we created previously in order to reflect any rating changes made by the submission.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;And finally put it on your page&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Render the partial in one of your views.&lt;/p&gt;


&lt;pre&gt;&lt;code class="html"&gt;&amp;lt;div id=&amp;quot;star-ratings-block&amp;quot;&amp;gt;
    &amp;lt;%= render :partial =&amp;gt; &amp;quot;rating/rating&amp;quot;, :locals =&amp;gt; { :asset =&amp;gt; @asset } %&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This needs @asset (or whatver you’re going to be using) in order to function.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Done&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Now wasn’t that easy? Gotta love rails. 10 minutes of coding and you have a complete Ajax and &lt;span class="caps"&gt;CSS&lt;/span&gt; star rating system just like the pros use. Here’s a &lt;a href="http://www.naffis.com/demos/rating_demo"&gt;demo&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;I could very well have skipped something so let me know if you have any problems.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/RubyRailsAndRandomness-Blog/~4/8udJr1yfMfY" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://naffis.com/2006/8/31/rails-ajax-star-rating-system</feedburner:origLink></entry>
  <entry xml:base="http://naffis.com/">
    <author>
      <name>dnaffis</name>
    </author>
    <id>tag:naffis.com,2006-08-28:29</id>
    <published>2006-08-28T13:29:00Z</published>
    <updated>2007-05-22T22:21:49Z</updated>
    <link href="http://feedproxy.google.com/~r/RubyRailsAndRandomness-Blog/~3/DROiIJFzzjE/washington-dc-ruby-on-rails-users-group" rel="alternate" type="text/html" />
    <title>Washington DC Ruby on Rails Users Group</title>
<content type="html">
            &lt;p&gt;I’m creating a Washington DC area Ruby on Rails Users Group. If you’re interested in getting involved check out &lt;a href="http://www.dcrug.org"&gt;www.dcrug.org&lt;/a&gt; for more information.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/RubyRailsAndRandomness-Blog/~4/DROiIJFzzjE" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://naffis.com/2006/8/28/washington-dc-ruby-on-rails-users-group</feedburner:origLink></entry>
  <entry xml:base="http://naffis.com/">
    <author>
      <name>dnaffis</name>
    </author>
    <id>tag:naffis.com,2006-08-20:28</id>
    <published>2006-08-20T22:39:00Z</published>
    <updated>2007-05-22T22:22:00Z</updated>
    <link href="http://feedproxy.google.com/~r/RubyRailsAndRandomness-Blog/~3/g33EjlLGR1c/rejectmail-com-free-receive-only-email" rel="alternate" type="text/html" />
    <title>RejectMail.com - Free Receive Only Email</title>
<content type="html">
            &lt;p&gt;&lt;a href="http://www.rejectmail.com"&gt;RejectMail.com&lt;/a&gt; is a free receive only email service.&lt;/p&gt;


	&lt;p&gt;Give out any address @rejectmail.com and then come to rejectmail.com to check your email or use the &lt;span class="caps"&gt;RSS&lt;/span&gt; feed provided for updates.&lt;/p&gt;


	&lt;p&gt;It’s a bit ugly right now but hopefully when I have some time I’ll clean it up and add a few more features.&lt;/p&gt;


	&lt;p&gt;Again, this was written entirely with Ruby on Rails.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/RubyRailsAndRandomness-Blog/~4/g33EjlLGR1c" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://naffis.com/2006/8/20/rejectmail-com-free-receive-only-email</feedburner:origLink></entry>
  <entry xml:base="http://naffis.com/">
    <author>
      <name>dnaffis</name>
    </author>
    <id>tag:naffis.com,2006-08-15:27</id>
    <published>2006-08-15T12:33:00Z</published>
    <updated>2007-05-22T22:22:30Z</updated>
    <link href="http://feedproxy.google.com/~r/RubyRailsAndRandomness-Blog/~3/DolTkX_NDus/adzmo-com-location-based-shopping-tool" rel="alternate" type="text/html" />
    <title>Adzmo.com - Location Based Shopping Tool</title>
<content type="html">
            &lt;p&gt;&lt;a href="http://www.adzmo.com"&gt;Adzmo.com&lt;/a&gt; is a location based shopping tool. By sending a short text message, 
like the one you see below, adzmo.com can tell you where the closest shops and
restaurants are.&lt;/p&gt;


	&lt;p&gt;Just sent a text message to any category of product, like pizza@adzmo.com. In 
the body of your message include the phone number of any nearby store, restaurant,
or merchant. Within seconds you’ll receive a detailed list of nearby merchants 
matching the category your provided.&lt;/p&gt;


&lt;p&gt;
&lt;img src="http://www.naffis.com/system/assets/intro_small.jpg"&gt;
&lt;/p&gt;

	&lt;p&gt;This one was also created with RoR.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/RubyRailsAndRandomness-Blog/~4/DolTkX_NDus" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://naffis.com/2006/8/15/adzmo-com-location-based-shopping-tool</feedburner:origLink></entry>
  <entry xml:base="http://naffis.com/">
    <author>
      <name>dnaffis</name>
    </author>
    <id>tag:naffis.com,2006-08-14:26</id>
    <published>2006-08-14T10:34:00Z</published>
    <updated>2008-04-15T20:21:04Z</updated>
    <link href="http://feedproxy.google.com/~r/RubyRailsAndRandomness-Blog/~3/5p_iM7yVAuk/receiving-emails-and-attachments-with-rails" rel="alternate" type="text/html" />
    <title>Receiving Emails and Attachments with Rails</title>
<content type="html">
            &lt;p&gt;Does your Rails app need to handle incoming emails with the attachments? All of the examples I’ve seen so far show you how to insert email attachments into the DB. Here’s a quick example that uses RailsCron to poll a &lt;span class="caps"&gt;POP3&lt;/span&gt; account every minute for new emails and stores the attachments on the filesystem. If you need help using or running RailsCron see my previous posts about the topic.&lt;/p&gt;


	&lt;p&gt;The Agile book has a good example that kicks off a runner script but I think this method is far more efficient than having your mail system kick off a separate runner every time a new email is received, especially if you’re dealing in high volume.&lt;/p&gt;


	&lt;p&gt;It also handles non-responsive or slow responding &lt;span class="caps"&gt;POP3&lt;/span&gt; servers by setting a high timeout length and retrying a handful of times before it gives up.&lt;/p&gt;


	&lt;p&gt;This class will check for and hand off any incoming emails:&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;require 'net/pop'

class EmailQueue &amp;lt; ActiveRecord::Base
  background :poll_mail, :every =&amp;gt; 1.minute, :concurrent =&amp;gt; false      

  def self.poll_mail
    retrycount = 0
    begin
      timeout(600) do
        Net::POP3.start(&amp;quot;yourdomain.com&amp;quot;, nil, &amp;quot;username&amp;quot;, &amp;quot;password&amp;quot;) do |pop|
          if pop.mails.empty?
            logger.info &amp;quot;NO MAIL&amp;quot; 
          else
            pop.mails.each do |email|        
              begin
                logger.info &amp;quot;receiving mail...&amp;quot; 
                AssetSubmitHandler.receive(email.pop)
                email.delete
              rescue Exception =&amp;gt; e
                logger.error &amp;quot;Error receiving email at &amp;quot; + Time.now.to_s + &amp;quot;::: &amp;quot; + e.message
              end          
            end
          end
        end
      end        
    rescue TimeoutError      
      if(retrycount &amp;lt; 5)
        retrycount+=1
        retry
      else
        logger.info(&amp;quot;ERROR Timeout error in poll_mail attempt #&amp;quot; + retrycount.to_s)
        nil
      end
    end  
  rescue Exception =&amp;gt; exception
    SystemNotifier.deliver_exception_notification(exception)   
    logger.info(&amp;quot;Error in poll_mail&amp;quot;)
    logger.info(exception.class.to_s + &amp;quot; &amp;quot; + exception.message.to_s + &amp;quot; &amp;quot; + exception.backtrace.to_s) 
  end    

end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;And here’s the code that handles the email:&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;class AssetSubmitHandler &amp;lt; ActionMailer::Base  

  # content type should be validated to image/gif, image/jpg, or image/jpeg
  def receive(email)
    if email.has_attachments?
      email.attachments.each do |attachment|
        asset = Asset.new
        asset.submitter = email.from.first        
        asset.name = base_part_of(attachment.original_filename)
        asset.content_type = attachment.content_type.chomp

        base_dir = &amp;quot;/home/someapp/www/&amp;quot;           

        # save original file
        asset.original = &amp;quot;assets/o_#{Time.now.utc.to_i}#{rand(1000000)}.&amp;quot;+asset.name
        File.open(base_dir+asset.original,File::CREAT|File::TRUNC|File::WRONLY,0666){ |f|
          f.write(attachment.read)
        }

        asset.save
      end
    end
  end

  def base_part_of(file_name)
    name = File.basename(file_name)
    name.gsub(/[^W._-]/, '')
    sanitize_filename(name)
  end

  # Fixes a 'feature' of IE where it passes the entire path instead of just the filename
  def sanitize_filename(value)
    #get only the filename (not the whole path)
    just_filename = value.gsub(/^.*(\\|\/)/, '')
    just_filename.gsub(/[^\w\.\-]/,'_') 
  end

end&lt;/code&gt;&lt;/pre&gt;
          &lt;img src="http://feeds.feedburner.com/~r/RubyRailsAndRandomness-Blog/~4/5p_iM7yVAuk" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://naffis.com/2006/8/14/receiving-emails-and-attachments-with-rails</feedburner:origLink></entry>
  <entry xml:base="http://naffis.com/">
    <author>
      <name>dnaffis</name>
    </author>
    <id>tag:naffis.com,2006-08-09:25</id>
    <published>2006-08-09T20:58:00Z</published>
    <updated>2007-05-22T22:25:30Z</updated>
    <link href="http://feedproxy.google.com/~r/RubyRailsAndRandomness-Blog/~3/FEvgILEtD34/rails-security-issue-and-fix" rel="alternate" type="text/html" />
    <title>Rails Security Issue and Fix</title>
<content type="html">
            &lt;p&gt;If you’re running Ruby on Rails you should do an update immediately to get the fix for a newly found security issue.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://weblog.rubyonrails.org/2006/8/9/rails-1-1-5-mandatory-security-patch-and-other-tidbits"&gt;Here’s some more info about it.&lt;/a&gt;&lt;/p&gt;


To upgrade run:
&lt;pre&gt;&lt;code class="ruby"&gt;gem install rails --include-dependencies&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Rails 1.0 and earlier versions as well as Rails 1.1.3 aren’t affected.&lt;/p&gt;


	&lt;p&gt;If you want to freeze your particular version of Rails for an app go to the root directory of that app and run:&lt;/p&gt;


&lt;pre&gt;&lt;code class="ruby"&gt;rake rails:freeze:gems&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&lt;i&gt;Note: The last release of rails (1.1.5) only solves part of the security problem. Update rails today to get 1.1.6.&lt;/i&gt;&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/RubyRailsAndRandomness-Blog/~4/FEvgILEtD34" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://naffis.com/2006/8/9/rails-security-issue-and-fix</feedburner:origLink></entry>
  <entry xml:base="http://naffis.com/">
    <author>
      <name>dnaffis</name>
    </author>
    <id>tag:naffis.com,2006-07-06:18</id>
    <published>2006-07-06T14:17:00Z</published>
    <updated>2007-05-22T22:29:34Z</updated>
    <category term="myspace" />
    <category term="projects" />
    <category term="rails" />
    <category term="ruby" />
    <link href="http://feedproxy.google.com/~r/RubyRailsAndRandomness-Blog/~3/Q9lF-sDNoD0/whatmyfriendslike-com" rel="alternate" type="text/html" />
    <title>WhatMyFriendsLike.com</title>
<content type="html">
            &lt;div&gt;
&amp;lt;center&gt;&lt;a href="http://www.whatmyfriendslike.com/app/user/items/21"&gt;
&lt;img src="http://www.whatmyfriendslike.com/assets/11537735018055218128.gif"&gt;&lt;br&gt;
See what my friends like!&lt;/a&gt;&amp;lt;/center&gt;&lt;/div&gt;

	&lt;p&gt;In addition to &lt;a href="http://www.naffis.com/msmaps/"&gt;MySpace Maps&lt;/a&gt; I also created &lt;a href="http://www.whatmyfriendslike.com"&gt;WhatMyFriendsLike.com&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;It lets you create a ranked list of all the music, movies and books your MySpace friends like.&lt;/p&gt;


	&lt;p&gt;This one was also written entirely in &lt;a href="http://www.rubyonrails.com"&gt;Ruby on Rails&lt;/a&gt; sharing most of the code with MySpace Maps.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/RubyRailsAndRandomness-Blog/~4/Q9lF-sDNoD0" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://naffis.com/2006/7/6/whatmyfriendslike-com</feedburner:origLink></entry>
  <entry xml:base="http://naffis.com/">
    <author>
      <name>dnaffis</name>
    </author>
    <id>tag:naffis.com,2006-07-06:21</id>
    <published>2006-07-06T12:35:00Z</published>
    <updated>2007-05-22T22:28:22Z</updated>
    <link href="http://feedproxy.google.com/~r/RubyRailsAndRandomness-Blog/~3/R_JWowyHcIM/multiple-railscron-instances" rel="alternate" type="text/html" />
    <title>Multiple RailsCron Instances</title>
<content type="html">
            &lt;p&gt;Just to follow up on my last post about using RailsCron.&lt;/p&gt;


	&lt;p&gt;If you want to run multiple instances of RailsCron you need to change the startup tasks in the rake file.&lt;/p&gt;


	&lt;p&gt;In my particular case I wanted a separate instance running for each of the sites that required it. I’m running them all as Daemons so I changed the cron_start target in my rake file.&lt;/p&gt;


From the root of of your app edit the rake file:
&lt;pre&gt;&lt;code class="ruby"&gt;vi vendor/plugins/trunk/tasks/startup.rake&lt;/code&gt;&lt;/pre&gt;

Change
&lt;pre&gt;&lt;code class="ruby"&gt;desc &amp;quot;Starts RailsCron as a daemon&amp;quot;
task :cron_start do
  if `#{sudo &amp;quot;ps x | grep RailsCron | grep -v grep&amp;quot;}`.strip.blank?
    mode = ENV['RAILS_ENV'] || &amp;quot;development&amp;quot;
    puts `#{sudo &amp;quot;nohup ruby script/runner -e #{mode} \&amp;quot;RailsCron.start\&amp;quot; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;&amp;quot;}`
  else
    puts &amp;quot;RailsCron already started&amp;quot;
  end
end&lt;/code&gt;&lt;/pre&gt;

To the following:
&lt;pre&gt;&lt;code class="ruby"&gt;desc &amp;quot;Starts RailsCron as a daemon&amp;quot;
task :cron_start do
    mode = ENV['RAILS_ENV'] || &amp;quot;development&amp;quot;
    puts `#{sudo &amp;quot;nohup ruby script/runner -e #{mode} \&amp;quot;RailsCron.start\&amp;quot; &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;&amp;quot;}`
end&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This removes the check for an existing RailsCron process and lets you start a new one. Be careful.&lt;/p&gt;


	&lt;p&gt;Now you can run rake cron_start from the root of each app that requires a RailsCron instance.
Running rake cron_stop will stop all the RailsCron processes so you’ll have to start each one up again.&lt;/p&gt;
          &lt;img src="http://feeds.feedburner.com/~r/RubyRailsAndRandomness-Blog/~4/R_JWowyHcIM" height="1" width="1"/&gt;</content>  <feedburner:origLink>http://naffis.com/2006/7/6/multiple-railscron-instances</feedburner:origLink></entry>
</feed>
