<?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>Danny Hawkins</title>
	<atom:link href="http://www.danhawkins.me.uk/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.danhawkins.me.uk</link>
	<description>Code &#039;n&#039; that</description>
	<lastBuildDate>Fri, 14 Oct 2011 22:58:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Generate I18n locale files from Rails views and models</title>
		<link>http://www.danhawkins.me.uk/2011/08/generate-i18n-locale-files-from-rails-views-and-models/</link>
		<comments>http://www.danhawkins.me.uk/2011/08/generate-i18n-locale-files-from-rails-views-and-models/#comments</comments>
		<pubDate>Fri, 19 Aug 2011 06:46:23 +0000</pubDate>
		<dc:creator>Danny</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ruby / Rails]]></category>

		<guid isPermaLink="false">http://www.danhawkins.me.uk/?p=174</guid>
		<description><![CDATA[I made a little rake task to allow you to scrape your views for translation calls, and also run through models and generate locale files. The model scraping allows the resulting file to be used with formtastic. There are plenty &#8230; <a href="http://www.danhawkins.me.uk/2011/08/generate-i18n-locale-files-from-rails-views-and-models/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I made a little rake task to allow you to scrape your views for translation calls, and also run through models and generate locale files. The model scraping allows the resulting file to be used with formtastic.</p>
<p>There are plenty of comments in the code, but if anyone has questions or problems please comment.</p>
<p>&nbsp;</p>
<pre class="brush:ruby">
require 'find'

class Hash
  # sets value at a dot seperated key path
  # key = 'general.name' = hash[:general][:name]
  def set_value_for_key(key, value)
    key_parts = key.split('.')
    if key_parts.length > 1
      key_part = key_parts[0]
      new_key = key_parts[1..-1].join('.')
      self[key_part] ||= {}
      self[key_part].set_value_for_key(new_key, value)
    else
      self[key] = value
    end
  end
end

module I18n
  def self.translation_exception(*args)
    locale = args[1] # => :en
    key = args[2] # => 'general.name'
    #load existing locale data
    locale_file = Rails.root.join("config/locales/#{locale}.yml")
    data = YAML.load_file(locale_file) if File.exists?(locale_file)
    data ||= {}
    # normalise the key
    normalized_key = I18n.normalize_keys(locale, key, []) # => [:general,:name]
    # used for the value if
    value_text = normalized_key[-1] # => :name
    # add to the hash
    data.set_value_for_key(normalized_key.join('.'), value_text.to_s.humanize)
    # save
    File.open(locale_file, "w") {|f| f.write( data.to_yaml) }
  end
end
# override default exception for translation exceptions
# this allows us to process missing translation with the above code
I18n.exception_handler = :translation_exception

namespace :translations do
  desc "Update translation yaml from views"
  task :from_views => :environment do
    assets = []
    #get all the view files
    Find.find(Rails.configuration.view_path) do |view|
      if File.file?(view) &#038;&#038; File.extname(view) == '.erb'
        File.readlines(view).each do |line|
          #look for t or I18n.t calls on each line, and append to assets
          assets += line.scan(/\st\(([^,\)]*)/).flatten
          assets += line.scan(/\sI18n.t\(([^,\)]*)/).flatten
        end
      end
    end
    #clean the keys up
    assets.map!{|a| a.gsub("'","").gsub(':','')}
    #sort so deep keys are last
    assets.sort!{|x,y| x.scan('.').count <=> y.scan('.').count}
    #for each locale
    I18n.available_locales.each do |locale|
      I18n.locale = locale
      #attempt to call translate for each key
      assets.each do |translation_key|
        I18n.t(translation_key)
      end
    end

  end

  desc "Update translation yaml from models"
  task :from_models => :environment do
    #require the model files so rails is aware of the model
    Find.find(Rails.root.join('app/models')) do |model_file|
      if File.file?(model_file) &#038;&#038; File.extname(model_file) == '.rb'
        require model_file
      end
    end
    #for each available locale
    I18n.available_locales.each do |locale|
      I18n.locale = locale
      #and each available model
      ActiveRecord::Base.descendants.each do |model|
        #in my case some models are for extension only and will not have a table
        #so using a rescue block lets the code keep on going
        begin
          model_name = model.name.underscore
          #for each column, try to access the translation
          model.columns.each do |col|
            I18n.t("activerecord.attributes.#{model_name}.#{col.name}".trim)
          end
        rescue Exception => ex
          #do nothing
        end
      end
    end
  end

  desc "Update translation yaml from all sources"
  task :from_all => [:from_views, :from_models]

end
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.danhawkins.me.uk/2011/08/generate-i18n-locale-files-from-rails-views-and-models/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Email to Ruby script to google calendar</title>
		<link>http://www.danhawkins.me.uk/2011/03/email-to-ruby-script-to-google-calendar/</link>
		<comments>http://www.danhawkins.me.uk/2011/03/email-to-ruby-script-to-google-calendar/#comments</comments>
		<pubDate>Thu, 10 Mar 2011 14:49:19 +0000</pubDate>
		<dc:creator>Danny</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ruby / Rails]]></category>

		<guid isPermaLink="false">http://www.danhawkins.me.uk/?p=150</guid>
		<description><![CDATA[We receive notifications at the office from the iDEAL payment system in the Netherlands when there is planned maintenance or disturbances. It&#8217;s pretty difficult to visualise the downtime in the text form we get it in, so I thought it &#8230; <a href="http://www.danhawkins.me.uk/2011/03/email-to-ruby-script-to-google-calendar/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>We receive notifications at the office from the iDEAL payment system in the Netherlands when there is planned maintenance or disturbances. It&#8217;s pretty difficult to visualise the downtime in the text form we get it in, so I thought it would be a good idea to try and get it into a calendar. It was surprisingly easy to accomplish, so I thought I would share a basic version of the script for anyone to use.</p>
<h3>Setup</h3>
<p>You will need Ruby (I was using 1.9.2-p180 via <a href="http://rvm.beginrescueend.com/">RVM</a>) the <a href="http://sites.google.com/site/benjaminfrancisoud/googlecalendar">googlecalendar gem</a> the <a href="https://github.com/mikel/mail">mail gem</a> and optionally <a href="http://nokogiri.org/">nokogiri</a> if you want to parse a multipart html message.</p>
<p>You can install all with: gem install googlecalendar mail nokogiri</p>
<p>You will need to add to your /etc/aliases file (for postfix) for other MTA&#8217;s please RTFM:</p>
<p>scriptaddress: &#8220;| /path/to/script.rb&#8221; </p>
<p>Where script address is the address where the message should be emailed to.</p>
<p>The skeleton script is below:</p>
<pre class="brush:ruby">
#!/usr/local/bin/ruby
require 'rubygems'
require 'nokogiri'
require 'googlecalendar'
require 'time'
require 'mail'

include Googlecalendar

#read the email in
email = Mail.new(STDIN.read)

#if it's a multipart message then email.parts[1].body.to_s will give me the HTML
#I can then use Nokogiri to give me a HTML doc
#html_doc = Nokogiri::HTML(email.parts[1].body.to_s)

g = GData.new
#logon to my account and fetch a token
token = g.login('danny.hawkins@gmail.com', 'yourpassword')

event = {
  :title      => email.subject,
  :content    => email.body,
  :author     => "dannyhawkins",
  :email      => "danny.hawkins@gmail",
  :where      => "London",
  :startTime  => "2011-03-10T15:00:00.000+00:00", #+00:00 means GMT +01:00 would be CET etc
  :endTime    => "2011-03-10T16:00:00.000+00:00"
}
#post my event
response = g.new_event(event)
#post my event to a different calendar
#response = g.new_event(event, 'calendar name')
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.danhawkins.me.uk/2011/03/email-to-ruby-script-to-google-calendar/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Running PHPUnit tests in a webpage</title>
		<link>http://www.danhawkins.me.uk/2011/03/running-phpunit-tests-in-a-webpage/</link>
		<comments>http://www.danhawkins.me.uk/2011/03/running-phpunit-tests-in-a-webpage/#comments</comments>
		<pubDate>Wed, 09 Mar 2011 20:51:18 +0000</pubDate>
		<dc:creator>Danny</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.danhawkins.me.uk/?p=145</guid>
		<description><![CDATA[Given that there isn&#8217;t currently built in support for PHPUnit testing in browser although it was being put into the roadmap according to an article by the author (http://sebastian-bergmann.de/archives/639-AJAX-Based-Test-Runner-for-PHPUnit.html#content) I took a script someone else had put together and modified &#8230; <a href="http://www.danhawkins.me.uk/2011/03/running-phpunit-tests-in-a-webpage/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Given that there isn&#8217;t currently built in support for PHPUnit testing in browser although it was being put into the roadmap according to an article by the author (<a href="http://sebastian-bergmann.de/archives/639-AJAX-Based-Test-Runner-for-PHPUnit.html#content">http://sebastian-bergmann.de/archives/639-AJAX-Based-Test-Runner-for-PHPUnit.html#content</a>) I took a script someone else had put together and modified it slightly. I can&#8217;t find the original script now so I apologies for not crediting the author. The script goes a little something like this</p>
<pre class="brush:php">
require_once('PHPUnit/Util/Log/JUnit.php');

function bfglob($path, $pattern = '*', $flags = 0, $depth = 0) {
  $matches = array();
  $folders = array(rtrim($path, DIRECTORY_SEPARATOR));

  while($folder = array_shift($folders)) {
    $matches = array_merge($matches, glob($folder.DIRECTORY_SEPARATOR.$pattern, $flags));
    if($depth != 0) {
      $moreFolders = glob($folder.DIRECTORY_SEPARATOR.'*', GLOB_ONLYDIR);
      $depth   = ($depth < -1) ? -1: $depth + count($moreFolders) - 2;
      $folders = array_merge($folders, $moreFolders);
    }
  }
  return $matches;
}

class SPTestRunner{
  public static function run(){
    // Create the test suite instance
    $suite = new PHPUnit_Framework_TestSuite();
    $suite->setName('SPTestRunner');

    $filenames = bfglob(__DIR__,"*Test.php",0,-1);
    // Add files to the TestSuite
    $suite->addTestFiles($filenames);

    // Create a xml listener object
    $listener = new PHPUnit_Util_Log_JUnit;

    // Create TestResult object and pass the xml listener to it
    $testResult = new PHPUnit_Framework_TestResult();
    $testResult->addListener($listener);

    // Run the TestSuite
    $result = $suite->run($testResult);

    // Get the results from the listener
    $xml_result = $listener->getXML();
    return $xml_result;
  }
}

$test_xml = SPTestRunner::run();
$simple = new SimpleXMLElement($test_xml);

$test_results = array();
$assertions = 0;
$time = 0.0;
$tests = 0;
foreach($simple->{'testsuite'}->testsuite as $testsuite){
  foreach($testsuite->testcase as $testcase){
    $result = array();
    $tests += 1;
    // Don't froget to cast SimpleXMLElement to string!
    $result['name'] = (string)$testcase['name'];
    $result['suite'] = (string)$testcase['class'];
    $assertions += $result['assertions'] = (string)$testcase['assertions'];
    $time += $result['time'] = (string)$testcase['time'];
    if(isset($testcase->{'failure'})){
      $result['result'] = 'Fail';
      $result['message'] = (string)$testcase->{'failure'};
    }else{
      $result['result'] = 'Pass';
      $result['message'] = '';
    }
    $test_results[] = $result;
  }
}
?>
<style type="text/css">
body{
  background:#333;
  font-family:Helvetica;
  font-size:11px;
}
table{
  width:90%;
  margin:0px auto;
  font-size:12px;
}

table th{
  text-align:left;
  background:#aaa;
  padding:4px;
}

table td{
  background:#fff;
  padding:4px;
  border-bottom:1px solid #999;
}

table td.test_pass{
  color:#3a3;
  text-transform:uppercase;
  font-weight:bold;
}

table td.test_fail{
  color:#a33;
  text-transform:uppercase;
  font-weight:bold;
}

tr.totals td{
  font-weight:bold;
  font-size:14px;
}

pre{
  background:#eee;
}
</style>
<table cellspacing="0" class="test_results">
<thead>
<tr>
<th>Suite</th>
<th>Test Name</th>
<th>Result</th>
<th>Message</th>
<th>Assertions</th>
<th>Time</th>
</tr>
</thead>
<tbody>
  <?php foreach($test_results as $test_result): ?>
<tr>
<td><?php echo $test_result['suite'] ?></td>
<td><?php echo $test_result['name'] ?></td>

      <?php if($test_result['result'] == 'Fail') : ?>
<td class="test_fail">Fail</td>

      <?php else: ?> 
<td class="test_pass">Pass</td>

      <?php endif; ?>
<td><?php echo $test_result['message'] ?></td>
<td><?php echo $test_result['assertions'] ?></td>
<td><?php echo $test_result['time'] ?></td>
</tr>

  <?php endforeach; ?>
<tr class="totals">
<td colspan="3"></td>
<td><?php echo $tests ?> TESTS</td>
<td><?php echo $assertions ?> ASSERTIONS</td>
<td><?php echo $time ?> SEC</td>
</tr>
</tbody>
</table>
</pre>
<p>It&#8217;s by no means pretty, but it does the job, just drop it in a folder at the root of your tests and it will look for all files including subdirectories that look like *Test.php and run them. Unfortunately because the script first has to wait for the XML to come back form PHPUnit you will not see the result of your tests until they have all finished running.</p>
<h3>AJAX PHPUnit Runner</h3>
<p>I&#8217;m hoping to find some time to able to realise an AJAX driven interface that allow you to select certain groups / tests / suites and run them in browser with realtime results. If anyway wants to lend me a hand I&#8217;m open to offers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danhawkins.me.uk/2011/03/running-phpunit-tests-in-a-webpage/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>We&#8217;re having a baby!</title>
		<link>http://www.danhawkins.me.uk/2011/03/were-having-a-baby/</link>
		<comments>http://www.danhawkins.me.uk/2011/03/were-having-a-baby/#comments</comments>
		<pubDate>Wed, 09 Mar 2011 20:38:58 +0000</pubDate>
		<dc:creator>Danny</dc:creator>
				<category><![CDATA[Homelife]]></category>

		<guid isPermaLink="false">http://www.danhawkins.me.uk/?p=141</guid>
		<description><![CDATA[Currently 11 weeks old, Baby Hawkins King is growing strong.]]></description>
			<content:encoded><![CDATA[<p>Currently 11 weeks old, Baby Hawkins King is growing strong.<br />
<a href="http://www.danhawkins.me.uk/2011/03/were-having-a-baby/191090_10150421120300790_790925789_17562425_605904_o/" rel="attachment wp-att-142"><img src="http://www.danhawkins.me.uk/wp-content/uploads/2011/03/191090_10150421120300790_790925789_17562425_605904_o.jpg" alt="Baby Hawkins King @ 11 wks" title="191090_10150421120300790_790925789_17562425_605904_o" width="900" height="621" class="alignnone size-full wp-image-142" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.danhawkins.me.uk/2011/03/were-having-a-baby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google4R Checkout and Rounding Policy</title>
		<link>http://www.danhawkins.me.uk/2010/10/google4r-checkout-and-rounding-policy/</link>
		<comments>http://www.danhawkins.me.uk/2010/10/google4r-checkout-and-rounding-policy/#comments</comments>
		<pubDate>Tue, 19 Oct 2010 04:11:52 +0000</pubDate>
		<dc:creator>Danny</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[checkout]]></category>
		<category><![CDATA[google-checkout]]></category>
		<category><![CDATA[google4r]]></category>
		<category><![CDATA[rounding]]></category>
		<category><![CDATA[rounding-policy]]></category>

		<guid isPermaLink="false">http://www.danhawkins.me.uk/?p=136</guid>
		<description><![CDATA[I&#8217;ve been using google4r-checkout for an integration of google checkout with one of my clients site. On the site I&#8217;m calculating VAT per line and by default I think google checkout does it per item. 90% of the time this &#8230; <a href="http://www.danhawkins.me.uk/2010/10/google4r-checkout-and-rounding-policy/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using <a href="http://github.com/danhawkins/google4r-checkout">google4r-checkout</a> for an integration of google checkout with one of my clients site. On the site I&#8217;m calculating VAT per line and by default I think google checkout does it per item. 90% of the time this was not causing a problem but occasionally it would be a penny out. To my disappointment I found that the google4r-checkout gem did not support rounding mode and rule as specified in the api <a href="http://code.google.com/apis/checkout/developer/Google_Checkout_XML_API_Rounding_Policy.html">here</a>. So I forked it on github, and made the changes. I thought it may be useful to others so feel free to use it <a href="http://github.com/danhawkins/google4r-checkout">http://github.com/danhawkins/google4r-checkout</a></p>
<p>The syntax is pretty simple:</p>
<pre class="brush:ruby">
      checkout_command = GoogleCheckout::Order.frontend.create_checkout_command
      checkout_command.rounding_rule = Google4R::Checkout::RoundingRule::PER_LINE
      checkout_command.rounding_mode = Google4R::Checkout::RoundingMode::HALF_UP
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.danhawkins.me.uk/2010/10/google4r-checkout-and-rounding-policy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails javascript specific layout</title>
		<link>http://www.danhawkins.me.uk/2010/08/rails-javascript-specific-layout/</link>
		<comments>http://www.danhawkins.me.uk/2010/08/rails-javascript-specific-layout/#comments</comments>
		<pubDate>Tue, 03 Aug 2010 12:03:13 +0000</pubDate>
		<dc:creator>Danny</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.danhawkins.me.uk/?p=118</guid>
		<description><![CDATA[Recently I&#8217;ve started to favour using small snippets of js.erb for each controller action over using one monolithic javascript controller designed to run the whole application. It means you have small manageable pieces of code which are only loaded when &#8230; <a href="http://www.danhawkins.me.uk/2010/08/rails-javascript-specific-layout/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Recently I&#8217;ve started to favour using small snippets of js.erb for each controller action over using one monolithic javascript controller designed to run the whole application. It means you have small manageable pieces of code which are only loaded when the app needs them, this is also good for your sites security as you do not expose everything at once in a .js file.</p>
<p>The problem I had was that I need to make sure notices are shown on ajax requests as well as normal requests. I started out by having a block of code at the bottom of each js.erb that would show notices like so:</p>
<pre class="brush:ruby">%('#notices').replaceWith('&lt;% escape_javascript(render :partial =&gt; "shared/notices")%&gt;');</pre>
<p>Which was all well and good except it&#8217;s not DRY, and didn&#8217;t feel very rails at all. My final solution involved using application.js.erb in layouts, which I didn&#8217;t even realise was possible. Check it out:</p>
<p>#application.js.erb</p>
<pre class="brush:ruby">
&lt;%= render :partial => "shared/notices" %&gt;

&lt;%= yield %&gt;
</pre>
<p>#shared/notices.js.erb</p>
<pre class="brush:ruby">if($('#notices')){
  $('#notices').replaceWith('&lt;% escape_javascript(render :partial =&gt; "shared/notices.html")%&gt;');
}else{
  notices = $('#header').before('&lt;% escape_javascript(render :partial =&gt; "shared/notices.html")%&gt;');
}</pre>
<p>#shared/notices.html.erb</p>
<pre class="brush:ruby">
<div id="notices">
  &lt;% if flash[:notice] %&gt;
<div class="notice">&lt;%= flash[:notice] %&gt;</div>

  &#038;lt% end %&gt;

  &lt;% if flash[:error] %&gt;
<div class="error">&gt;%= flash[:error] %&gt;</div>

  &lt;% end %%gt;

  &lt;%= link_to "close", "#", :class => "close" %&gt;
  &lt;% javascript_tag do %&gt;
    noticesTimer = setTimeout(function(){ $('#notices').slideUp()}, 5000);
    $('#notices .close').click(function(){$('#notices').slideUp(); return false; });
  &lt;% end %&gt;
</div>
</pre>
<p>It will only load notices if needed, replace any #notices if it already exists and self hide afterwards.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danhawkins.me.uk/2010/08/rails-javascript-specific-layout/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The Battery Guys, Number 1 for car batteries</title>
		<link>http://www.danhawkins.me.uk/2010/07/the-battery-guys-number-1-for-car-batteries/</link>
		<comments>http://www.danhawkins.me.uk/2010/07/the-battery-guys-number-1-for-car-batteries/#comments</comments>
		<pubDate>Sun, 18 Jul 2010 21:13:27 +0000</pubDate>
		<dc:creator>Danny</dc:creator>
				<category><![CDATA[Clients]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[clients]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[seo]]></category>
		<category><![CDATA[thebatteryguys]]></category>

		<guid isPermaLink="false">http://www.danhawkins.me.uk/?p=109</guid>
		<description><![CDATA[I was pretty chuffed to find that after over a year of optimisation, hard work and good service one of my favourite clients thebatteryguys.co.uk have reached the top of googles search results for the term &#8220;car batteries&#8221; and are second &#8230; <a href="http://www.danhawkins.me.uk/2010/07/the-battery-guys-number-1-for-car-batteries/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I was pretty chuffed to find that after over a year of optimisation, hard work and good service one of my favourite clients <a title="The Battery Guys" href="http://thebatteryguys.co.uk" target="_blank">thebatteryguys.co.uk</a> have reached the top of googles search results for the term &#8220;car batteries&#8221; and are second for the term &#8220;car battery&#8221;.</p>
<p><a rel="attachment wp-att-113" href="http://www.danhawkins.me.uk/2010/07/the-battery-guys-number-1-for-car-batteries/batteryguys_seo_1/"><img class="alignnone size-full wp-image-113" title="batteryguys_seo_1" src="http://www.danhawkins.me.uk/wp-content/uploads/2010/07/batteryguys_seo_1.jpg" alt="" /></a></p>
<p>This has always been a long term goal of thebatteryguys.co.uk, who started of by spending a considerable amount on CPC advertising in order to allow people to be made aware of their top class service. Their core business is next day delivery of batteries for the automative industry. I did not anticipate that in such a short period of time they would have gained this much momentum and achieved the number 1 spot, the optimisations we have made to the site have contributed towards the result, but it&#8217;s also plain to see that the amazing service these guys offer has been talked about and people have come to the site through recommendations and not just advertising. Well done guys.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danhawkins.me.uk/2010/07/the-battery-guys-number-1-for-car-batteries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Acts As State Machine error handling</title>
		<link>http://www.danhawkins.me.uk/2010/07/acts-as-state-machine-error-handling/</link>
		<comments>http://www.danhawkins.me.uk/2010/07/acts-as-state-machine-error-handling/#comments</comments>
		<pubDate>Wed, 07 Jul 2010 14:42:28 +0000</pubDate>
		<dc:creator>Danny</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[aasm]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[gems]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.danhawkins.me.uk/?p=106</guid>
		<description><![CDATA[What is it? Acts as state machine (AASM) is a rubygem for adding finite state machines to Ruby classes. http://github.com/rubyist/aasm. This is a widely used gem/plugin and is the de-facto standard for state management in Ruby on Rails. Whilst working &#8230; <a href="http://www.danhawkins.me.uk/2010/07/acts-as-state-machine-error-handling/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h3>What is it?</h3>
<p>Acts as state machine (AASM) is a rubygem for adding finite state machines to Ruby classes. <a href="http://github.com/rubyist/aasm" target="_blank">http://github.com/rubyist/aasm</a>. This is a widely used gem/plugin and is the de-facto standard for state management in Ruby on Rails.</p>
<p>Whilst working on the Technophobia Video Uploader (coming soon!!!) I hit a problem with aasm.  I&#8217;ve used the gem before and think it can be overkill for certain situations but when used correctly has massive benefits.</p>
<h3>How it works</h3>
<p>The way acts as state machine works is by defining various states and event. The events have rules that determine which state transitions can take place and callbacks which allow functions to be executed at various stages of the transition. Take the code below for example:</p>
<pre class="brush:ruby">
 # State Machine
  aasm_column :status
  aasm_initial_state :pending

  aasm_state :pending
  aasm_state :encoded, :enter => :encode_video
  aasm_state :uploaded, :enter => :upload_video

  aasm_state :encode_failed
  aasm_state :upload_failed
  aasm_state :complete

  # State Machine Transitions
  aasm_event :encode do
    transitions :from => :pending, :to => :encoded
  end

  aasm_event :upload do
    transitions :from => :encoded, :to => :uploaded
  end

  aasm_event :complete do
    transitions :from => :uploaded, :to => :complete
  end

  aasm_event :failed do
    transitions :from => :pending, :to => :encode_failed
    transitions :from => :encoded, :to => :upload_failed
  end
</pre>
<p>This gives me 4 events that will cause the Objects state to move through 6 defined states. By calling Object.encode! I fire the encode event which will transition from the pending state to the encoded state going through any callbacks on the way. The callback method &#8220;encode_video&#8221; defined for the encode event is fired on entry into the transition. If the object state is anything other than pending I will get and InvalidStateTransition error as the encode! event should only allow pending objects to be processed.</p>
<h3>The problem</h3>
<p>The sequence which the callbacks and state change is called can be problematic, in the example above I use the enter callback to execute a method &#8220;encode_video&#8221;, this callback fires before the event status is changed.</p>
<pre class="brush:ruby">
    #callbacks and state change
    state.call_action(:before_enter, self)
    state.call_action(:enter, self) #our callback is executed
    self.aasm_current_state = state_name #the state is changed
    state.call_action(:after_enter, self)
</pre>
<p>This which works great unless you need to change state within the callback method, for example if the callback fails and you change the state to failed.<br />
In my encode_video method I check to see if the process has been successful and if not I call the failed! event, this works and sets the status to the appropriate failure status. However when control is returned to the block of code above, the line &#8220;self.aasm_current_state = state_name&#8221; changes the state from my failure state to the state as defined in the transition.</p>
<h3>The Solution</h3>
<p>Fortunately there is a very simple solution do this. You can pass the :error option into the aasm_event method to set a callback that will be used when a StandardError is raised within one of the state callbacks. This will allow the program to keep running but will break out of the code at the correct point before the state is changed. So we change the state machine transitions like so:</p>
<pre class="brush:ruby">
  # State Machine Transitions
  aasm_event :encode, :error => :error_raised do
    transitions :from => :pending, :to => :encoded
  end

  aasm_event :upload, :error => :error_raised do
    transitions :from => :encoded, :to => :uploaded
  end

  aasm_event :complete, :error => :error_raised do
    transitions :from => :uploaded, :to => :complete
  end
</pre>
<p>Then define the error method:</p>
<pre class="brush:ruby">
  def error_raised(error)
    failed!
    logger.debug("Error raised in video_encoding #{error.message}")
  end
</pre>
<p>And finally raise the correct error class in the call back function:</p>
<pre class="brush:ruby">

  def encode_video
    begin
      encoder = VideoChimp::Encoder.new
      case encoding_profile.container
        when "mp4" then
          encoder.encode_mp4
        when "flv" then
          encoder.encode_flv
      end
      unless encoder.valid?
        raise StandardError.new("Something went wrong encoding")
      end
    rescue Exception => ex
      raise StandardError.new("Exception in encode_video #{ex.message}")
    end
  end
</pre>
<p>And thats it. More control over your state machine <img src='http://www.danhawkins.me.uk/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.danhawkins.me.uk/2010/07/acts-as-state-machine-error-handling/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unobtrusive javascript with Rails 2.3.5</title>
		<link>http://www.danhawkins.me.uk/2010/05/unobtrusive-javascript-with-rails-2-3-5/</link>
		<comments>http://www.danhawkins.me.uk/2010/05/unobtrusive-javascript-with-rails-2-3-5/#comments</comments>
		<pubDate>Tue, 11 May 2010 21:26:49 +0000</pubDate>
		<dc:creator>Danny</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[2.3.5]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ujs]]></category>
		<category><![CDATA[unobtrusive]]></category>

		<guid isPermaLink="false">http://www.danhawkins.me.uk/?p=99</guid>
		<description><![CDATA[This is my handy little bit of javascript to make it easier to do UJS in Rails 2.3.5. Create a file within your public/javascripts folder called ajax.js containing the following: //unobtrusive javascript replacements //setup for format.js block $.ajaxSetup({ 'beforeSend': function(xhr) &#8230; <a href="http://www.danhawkins.me.uk/2010/05/unobtrusive-javascript-with-rails-2-3-5/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is my handy little bit of javascript to make it easier to do UJS in Rails 2.3.5. Create a file within your public/javascripts folder called ajax.js containing the following:</p>
<pre class="brush:javascript">
//unobtrusive javascript replacements
//setup for format.js block
$.ajaxSetup({
	'beforeSend': function(xhr) { xhr.setRequestHeader('Accept', 'text/javascript') }
});

//for replacing remote_form_form
$.fn.submitWithAjax = function(){
	this.live('submit',function(){
		$.ajax({
			url: $(this).attr("action"),
			type: ($(this.form).find("[name=_method]").attr('value') == undefined) ? 'post' : $(this.form).find("[name=_method]").attr('value'),
			data: $(this).serialize(),
			dataType: 'script'
		});
		return false;
	});
}

//for replacing link_to_remote
$.fn.linkWithAjax = function(){
	//add new click binding
	this.live('click',function(){
		$.ajax({
			url: this.href,
			type: $(this).is('.delete') ? 'delete' : 'get',
			dataType: 'script'
		});
		return false;
	});
}

//Bind links and forms on load
$(function(){
	$('a.remote').linkWithAjax();
	$('form.remote').submitWithAjax();
});
</pre>
<p>Then  include <a href="http://code.jquery.com/jquery-1.4.2.min.js" target="_blank">jquery 1.4.2 min</a> and ajax.js in your header, my javascript include line looks like this:</p>
<pre class="brush:ruby">
  javascript_include_tag 'jquery','jquery-ui','jrails','ajax', :cache => true
</pre>
<p>Then all you have to do is give the form_for or link_to tags a class of remote, if you want to delete make sure you give the link a class of delete too. <strong>Please note the ajax.js file I have created expects a script back, but you can pass expect html or text content by removing dataType: &#8216;script&#8217; </strong></p>
<p>If you do remove the dataType: &#8216;script&#8217; option you may want to add a success function. so&#8230;</p>
<pre class="brush:javascript">
     this.live('click',function(){
		$.ajax({
			url: this.href,
			type: $(this).is('.delete') ? 'delete' : 'get',
			success: function(data){
                             alert(data);
                        }
		});
		return false;
	});
</pre>
<p>Hope it helps, post a comment if you have a question.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.danhawkins.me.uk/2010/05/unobtrusive-javascript-with-rails-2-3-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SRC10 &#8211; De-normalising rails applications</title>
		<link>http://www.danhawkins.me.uk/2010/05/src10-de-normalising-rails-applications/</link>
		<comments>http://www.danhawkins.me.uk/2010/05/src10-de-normalising-rails-applications/#comments</comments>
		<pubDate>Tue, 11 May 2010 08:49:42 +0000</pubDate>
		<dc:creator>Danny</dc:creator>
				<category><![CDATA[Conferences]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[SRC10]]></category>

		<guid isPermaLink="false">http://www.danhawkins.me.uk/?p=93</guid>
		<description><![CDATA[Presented by: Daniel Lucraft &#38; Matt Wynne De-normalisation is just one of many strategies to cope with the scaling requirements of an application. It is the process of devising a method to group relevant data together in an optimal way &#8230; <a href="http://www.danhawkins.me.uk/2010/05/src10-de-normalising-rails-applications/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Presented by: Daniel Lucraft &amp; Matt Wynne</p>
<p>De-normalisation is just one of many strategies to cope with the scaling requirements of an application. It is the process of devising a method to group relevant data together in an optimal way for the system to return what is required quickly.</p>
<p>During the talk Daniel and Matt explained how Songkick has devised a series of classes to implement a de-normalisation strategy using a key value store in a document based database (MongoDB).</p>
<p>They use the Model View Presenter (MVP Presenter first) design pattern to serve up content for the views on the website. Presenters are first class domain objects tailored for displaying a single page or module of information. So when looking at information on the site you are actually seeing content returned from a document store through the Presenter.</p>
<p>This however presents it’s own bunch of problems. The first and probably most obvious is consistency. Unlike caching, content is not expired and then re-generated on demand, content will be regenerated as and when it is created or updated.</p>
<h3>Presenter, Soli and Silovator</h3>
<p> A presenter is basically a model which has methods to get only the data required for the view element and store these in the specific document. A typical presenter looks like this:</p>
<pre class="brush:ruby">
class EventListingPresenter

  def initialize(event)
    @event = event
  end

  def title;            @event.artists.map(&#038;:name).to_sentance;   end
  def image_count;      @event.images.count;                      end
  def attendance_count; @event.attending_users.count;             end

  #silo creates document on save using silo methods

  silo_method :title
  silo_method :image_count
  silo_method :attendance_count

ends
</pre>
<p>The silo_method works in a similar way to memoization. Data will attempt to return from the document store and failover to using the actual database through ActiveRecord.</p>
<h3>Cache control</h3>
<p>Cache expiration is controlled through asynchronous observers called Silovators. These silovators listen for events like create, update and delete on objects and run processes to generate the presenter data for any given presenter. For example:</p>
<pre class="brush:ruby">
class EventListingSilovator < AsyncObserver

  listen :create, Attendance do
    Silo.generate(presenter_for(attendance.event))
  end

  listen :update, Venue do
    venue.events.each do |event|
      Silo.generate(presenter_for(event.venue))
    end
  end
end
</pre>
<p>The silovator processes could be running on any number of machines, which creates another problem with possible race conditions. This is solved using <a href="http://github.com/songkick/mega_mutex">http://github.com/songkick/mega_mutex</a> which will ensure when a job is picked up, no other client will run that job at the same time. Megamutex uses memcache-client so your environment must be setup to use it.</p>
<p> Songkick have multiple background tasks which consume events and perform actions, these include ImageResizer, EmailNotifier and Silovater which all take advantage of mega_mutex to guarantee consistency.</p>
<h3>Resources</h3>
<ul>
<li><a href="http://www.atomicobject.com/files/PF_March2005.pdf"> http://www.atomicobject.com/files/PF_March2005.pdf </a></li>
<li><a href="http://github.com/songkick/mega_mutex">http://github.com/songkick/mega_mutex </a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.danhawkins.me.uk/2010/05/src10-de-normalising-rails-applications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

