<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Logical Friday</title>
	<atom:link href="http://logicalfriday.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://logicalfriday.com</link>
	<description>Mint Digital&#039;s tech blog</description>
	<lastBuildDate>Thu, 02 May 2013 11:16:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='logicalfriday.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://0.gravatar.com/blavatar/4f2f4772e6f3885fda6b387fd5daa90e?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Logical Friday</title>
		<link>http://logicalfriday.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://logicalfriday.com/osd.xml" title="Logical Friday" />
	<atom:link rel='hub' href='http://logicalfriday.com/?pushpress=hub'/>
		<item>
		<title>Midem Music Hackday 2013</title>
		<link>http://logicalfriday.com/2013/01/29/midem-music-hackday-2013/</link>
		<comments>http://logicalfriday.com/2013/01/29/midem-music-hackday-2013/#comments</comments>
		<pubDate>Tue, 29 Jan 2013 18:24:35 +0000</pubDate>
		<dc:creator>Rodreegez</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://logicalfriday.com/?p=787</guid>
		<description><![CDATA[Carrying on from my post on the Mint site, I wanted to share a little more information on what I think was the coolest part of my MIDEM Music Hackday hack &#8211; the technology. But first a quick recap of the idea for those in the dark: To answer the question &#8220;what do you listen [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=logicalfriday.com&#038;blog=22779237&#038;post=787&#038;subd=logicalfriday&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Carrying on from <a href="http://mintdigital.com/blog/midem-musichackday-2013">my post on the Mint site</a>, I wanted to share a little more information on what I think was the coolest part of my MIDEM Music Hackday hack &#8211; the technology.</p>
<p>But first a quick recap of the idea for those in the dark:</p>
<p>To answer the question &#8220;what do you listen to?&#8221; I created an app that analyses your recent listening history and awards Artist, Genre, Guilty Pleasure and Hipster badges based on certain criteria.</p>
<p>With that out of the way…</p>
<p><span id="more-787"></span></p>
<p><strong>The Tech</strong><br />
While the idea itself is hardly revolutionary, and the website itself is not quite all there (it would have looked a lot less pretty if <a href="https://twitter.com/benbaudart">Ben</a> hadn&#8217;t made those beautiful badges for me. Thanks again, Ben!), I tried something new on the back-end. The application is built in Rails, and contains 2 models &#8211; the User model and the Badge model &#8211; which run to 18 and 5 lines respectively. As I haven&#8217;t hooked up all the moving parts (you&#8217;ll notice I triggered everything from the command line in <a href="http://www.youtube.com/watch?feature=player_embedded&amp;v=gSYD5wABAgY&amp;list=PL8828QLbgLTrrInS9appu0z2NbH4kF8zU#!%23t=0h22m50s">my presentation</a>), there are no real controllers. The traditional Rails code is so minimal because I made a real effort to pull &#8220;business logic&#8221; out into lib classes. This is the first time that I&#8217;ve really tried to do this, and I really tried to push the concept as far as I could. My ./lib folder looks something like this: </p>
<p><code><br />
lib<br />
…<br />
├── badge_calculator.rb<br />
├── echonest.rb<br />
├── emo_badge.rb<br />
├── fan_badge.rb<br />
├── fetcher.rb<br />
├── genre_badge.rb<br />
├── guilty_pleasure.rb<br />
├── hipster_badge.rb<br />
├── listens.rb<br />
…<br />
</code></p>
<p>I&#8217;ve omitted standard Rails boilerplate stuff, but you can see that there is a lot of logic in here. `badge_calculator.rb` kicks off the calculation process, and calls the calculate method defined in the classes of each badge, each of which is held in the appropriately named file. `fetcher.rb` does the fetching of the Last.fm data and Listens is a class that allows me to load that data in a nice Ruby format.</p>
<p>The result is highly modular code that was easy to test. I still need to push it further &#8211; all the badges should inherit from some kind of base badge class, and each badge duplicates pretty much the same awarding logic, which should be pulled out into a new class.</p>
<p>All in all I learned a hell of a lot in how to design a system like this. I&#8217;m sure it won&#8217;t be suitable in every situation, but it&#8217;s certainly something I will be doing more of in my work at Mint.</p>
<p>I also created a small Ruby gem to wrap the Gracenote Web API. It only does what I need it to right now, but I&#8217;ve stuck it up <a href="https://github.com/rodreegez/gracenote">on GitHub</a> so if you want to extend it, please do!</p>
<p><strong>What next?</strong><br />
I still plan to work on this, make those changes mentioned above and hook everything up. When that&#8217;s done, I&#8217;ll push the app live and you can give it a go. I&#8217;m really interested in trying out the Facebook listens stuff too.</p>
<p>I&#8217;d love to hear any feedback. Do you love it? Hate it? Have an idea for a badge? Let me know.</p>
<p>Thanks again to <a href="https://twitter.com/martynrdavies">Martyn Davies</a>, the MIDEM crew, <a href="https://soundcloud.com/">SoundCloud</a> all the participants and anyone that asked us questions, stopped by to say hello, or were confused about what the hell we were doing. You all made it a really, really great event!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/logicalfriday.wordpress.com/787/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/logicalfriday.wordpress.com/787/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=logicalfriday.com&#038;blog=22779237&#038;post=787&#038;subd=logicalfriday&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://logicalfriday.com/2013/01/29/midem-music-hackday-2013/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/087f948e082987b362468e2a9aa1e121?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">rodreegez</media:title>
		</media:content>
	</item>
		<item>
		<title>Sneaking a peak at Rails 4</title>
		<link>http://logicalfriday.com/2012/10/15/sneaking-a-peak-at-rails-4/</link>
		<comments>http://logicalfriday.com/2012/10/15/sneaking-a-peak-at-rails-4/#comments</comments>
		<pubDate>Mon, 15 Oct 2012 11:23:40 +0000</pubDate>
		<dc:creator>Rodreegez</dc:creator>
				<category><![CDATA[Back-end development]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://logicalfriday.com/?p=761</guid>
		<description><![CDATA[This weekend I decided to have a go at making an app with edge Rails, aka Rails 4.0.0.beta. I hunted around for a summary of the cool new stuff and didn&#8217;t really find one. So, here is the interesting things I hit upon, more or less in the order I hit upon them: Getting started: [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=logicalfriday.com&#038;blog=22779237&#038;post=761&#038;subd=logicalfriday&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>This weekend I decided to have a go at making an app with edge Rails, aka Rails 4.0.0.beta. I hunted around for a summary of the cool new stuff and didn&#8217;t really find one. So, here is the interesting things I hit upon, more or less in the order I hit upon them:</p>
<p><span id="more-761"></span></p>
<p><strong>Getting started:</strong><br />
The first thing to do was to get `rails new` to generate a new app. After a little googling, it seems like the easiest way to do this is as follows:</p>
<p>* git clone git://github.com/rails/rails.git<br />
* cd rails<br />
* bundle install<br />
* railties/bin/rails new ../path/to/your_new_app &#8211;dev</p>
<p>So essentially, we get the latest in the rails repo, install its dependencies, and then run `rails new` from the binary in the repo. It&#8217;s important we pass the `&#8211;dev` flag so as to get the Gemfile pointing some Rails&#8217;  dependencies at you local copy of Rails. More info on this can be found in <a href="https://github.com/rails/rails/issues/7773">this ticket</a>.</p>
<p><strong>Routing concerns:</strong><br />
This is cool. While I didn&#8217;t really need to use it for what I was doing I figured little could go wrong with gratuitous use of beta features, so I went right ahead. Essentially, we are able to define a resource that can then become a &#8220;concern&#8221; of another resource. Something like this:</p>
<p><code>concern :hookable do<br />
  resources :hooks<br />
end<br />
resources :app, concerns: :hookable<br />
</code></p>
<p>Running `rake routes` shows us something like what can be seen in this gist (damn you wordpress.com): <a href="https://gist.github.com/3886049" rel="nofollow">https://gist.github.com/3886049</a></p>
<p>As you can see, adding the &#8220;concern&#8221; to another resource, adding hookable to app in this case, creates all the correct routes for the nested resource. Any resource can be &#8220;hookable&#8221;! The <a href="https://github.com/rails/routing_concerns">routing concerns</a> Readme uses the example of adding comments to a few different resources. I&#8217;m sure you can see how this coud be really useful in keeping your routes sane in certain situations.</p>
<p><strong>Turbolinks:</strong><br />
<a href="https://github.com/rails/turbolinks">Turbolinks</a> are an extension of the same idea as <a href="https://github.com/defunkt/jquery-pjax">pjax</a>, but this time applied to the whole page. When following a link, rails will update the body tag of the current page with the HTML for the new page, leaving everything else intact in an effort to reduce page load times. Turbolinks are enabled by default, and I did notice them doing their thing while developing my app. I don&#8217;t really have much to say on them right now. I think they made the page load feel snappier, but with such a basic page it&#8217;s hard to say. I didn&#8217;t do any benchmarking, and I&#8217;d imagine the performance benefits will vary depending on your situation. </p>
<p><strong>Testing:</strong><br />
I found this interesting. Gone are unit tests. Gone are functional tests. These have been replaced by model and controller tests. I think that makes much more sense.</p>
<p>Our new test directory looks a little like this after generating a couple of resources:</p>
<p><code>test/<br />
├── controllers<br />
│   ├── apps_controller_test.rb<br />
│   └── hooks_controller_test.rb<br />
├── fixtures<br />
│   ├── apps.yml<br />
│   └── hooks.yml<br />
├── helpers<br />
│   ├── apps_helper_test.rb<br />
│   └── hooks_helper_test.rb<br />
├── integration<br />
├── mailers<br />
├── models<br />
│   ├── app_test.rb<br />
│   └── hook_test.rb<br />
├── performance<br />
│   └── browsing_test.rb<br />
└── test_helper.rb</code></p>
<p><strong>Strong Parameters / Mass-assignment</strong><br />
Previously, there have been a number of ways to deal with mass-assignment. Rails 4 standardises this (rightly or wrongly) with Strong Parameters, which has been merged into rails core. Now, defining attr_accessable in our model will lead to an error a bit like this one: <code>RuntimeError (`attr_accessible` is extracted out of Rails into a gem. Please use new recommended protection model for params or add `protected_attributes` to your Gemfile to use old one.)</code>. Strong parameters are the recommended way, so let&#8217;s have a go:</p>
<p><code># controllers/apps_controller.rb<br />
  def create<br />
    @app = App.new(app_params)<br />
    if @app.save<br />
      redirect_to app_path(@app), notice: 'Created'<br />
    else<br />
      render :new, alert: 'Failed'<br />
    end<br />
  end</p>
<p>  private</p>
<p>  def app_params<br />
    params.require(:app).permit(:title, :password)<br />
  end<br />
</code></p>
<p>The assignment logic is encapsulated in a private method in the controller, and we use this to permit certain values in the params hash for the object we&#8217;re interested in. You can read more in the project&#8217;s <a href="https://github.com/rails/strong_parameters">Readme</a>, but note this is now part of Rails core.</p>
<p><strong>Queueing</strong><br />
Rails 4 ships with a simple queuing module. I think this is a greatly anticipated feature, and may folks have written more eloquently on the feature that I have. The gist of it is a job is a class that responds to <code>run</code>, and we push this onto the queue like this: </p>
<p><code>Rails.queue.push(SomeClassThatRespondsToRun.new)</code></p>
<p>I couldn&#8217;t find a generator for creating a job class, so I&#8217;m not overly sure of the convention that we&#8217;re supposed to follow, but I created a <code>jobs</code> directory under <code>app</code> and popped a <code>MyJob</code> class in there. Here&#8217;s a simplified example:</p>
<p><code>class MyJob<br />
  def initialize(id)<br />
    @id</span> = id<br />
  end</p>
<p>  def run<br />
    Thing.find(@id).heavy_lifting!<br />
  end<br />
end</code></p>
<p>And we call it with:</p>
<p><code>Rails.queue.push(MyJob.new(@thing.id))</code></p>
<p>Rails will spawn a worker process and process our queue in the background from there. For an interesting look into how <code>Rails.queue</code> is implemented, <a href="http://reefpoints.dockyard.com/ruby/2012/06/25/rails-4-sneak-peek-queueing.html">this is a good article</a> and <a href="https://github.com/rails/rails/blob/master/activesupport/lib/active_support/queueing.rb">the source</a> is enlightening too. </p>
<p><strong>Conclusion</strong><br />
I&#8217;m liking Rails 4! On balance I think things are moving in the right direction. We&#8217;re getting built-in support for stuff that happens in almost every project i.e. queuing, the new test directory structure makes more sense, to me at least, and anything to help make routing easier is something I&#8217;ll always appreciate.</p>
<p>I&#8217;m looking forward to dipping in to the source a little more, and following the development to the 4.0 release. I can&#8217;t wait!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/logicalfriday.wordpress.com/761/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/logicalfriday.wordpress.com/761/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=logicalfriday.com&#038;blog=22779237&#038;post=761&#038;subd=logicalfriday&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://logicalfriday.com/2012/10/15/sneaking-a-peak-at-rails-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/087f948e082987b362468e2a9aa1e121?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">rodreegez</media:title>
		</media:content>
	</item>
		<item>
		<title>iOS 6 injecting should_group_accessibility_children to POST requests</title>
		<link>http://logicalfriday.com/2012/10/03/ios-6-injecting-should_group_accessibility_children-to-post-requests/</link>
		<comments>http://logicalfriday.com/2012/10/03/ios-6-injecting-should_group_accessibility_children-to-post-requests/#comments</comments>
		<pubDate>Wed, 03 Oct 2012 13:28:34 +0000</pubDate>
		<dc:creator>Thomas Pomfret</dc:creator>
				<category><![CDATA[Back-end development]]></category>

		<guid isPermaLink="false">http://logicalfriday.com/?p=720</guid>
		<description><![CDATA[After iOS 6 dropped, we got reports that an iPhone app of ours had stopped working after upgrading. We quickly confirmed that this was indeed the case and started to investigate. To set the scene here, this is a native iOS app, which speaks to a Rails based API. Initially we thought that this might [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=logicalfriday.com&#038;blog=22779237&#038;post=720&#038;subd=logicalfriday&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>After iOS 6 dropped, we got reports that an iPhone app of ours had stopped working after upgrading. We quickly confirmed that this was indeed the case and started to investigate.</p>
<p><span id="more-720"></span></p>
<p>To set the scene here, this is a native iOS app, which speaks to a Rails based API. Initially we thought that this might be related to the reported <a href='http://stackoverflow.com/questions/12506897/is-safari-on-ios-6-caching-ajax-results'>&#8216;iOS 6 breaks POST requests&#8217;</a> issue, but after some investigation it became apparent that form fields from any POST reqs were getting the param should_group_accessibility_children (or shouldGroupAccessibilityChildren) injected into them. </p>
<p>When this extra param hits the API and we call something such as:<br />
<code><br />
@user = User.new(params[:user])<br />
@user.save<br />
</code></p>
<p>Rails will throw an exception as the User model is not aware of the should_group_accessibility_children attribute.  This will in turn return a 500 to the iOS client, which will display an error to the user.</p>
<p>For a quick fix, we monkey-patched AR::Base to add this attribute and subsequently ignore it. This worked fine, but just didn&#8217;t feel right. We then decided to see if it was possible to parse out these params using middleware, which indeed it is.</p>
<p>We have since released <a href='https://rubygems.org/gems/rack-remove-param'>rack-remove-param</a>, which can be used to solve exactly this. It&#8217;s actually a little more general however, you can use it to filter out any params you might not want hitting your application.</p>
<p>To use, simply add the gem to your Gemfile and then the following to your application.rb:<br />
<code><br />
config.middleware.insert 'Rack::RemoveParam', 'should_group_accessibility_children'<br />
</code></p>
<p>There doesn&#8217;t seem to be much info out there on what this param is (why you would add unknown form fields to reqs is another question!), but it seems to be related to some new <a href='https://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIAccessibility_Protocol/Introduction/Introduction.html#//apple_ref/occ/instp/NSObject/shouldGroupAccessibilityChildren'>accessibility features</a>. If anyone has more info, then please comment.</p>
<p><strong>Update</strong></p>
<p>Ok, so thanks to some comments and further discussion internally we can offer some answers to this.</p>
<p>iOS6 <em>does not</em> inject this param to POST requests. iOS has for some time added properties related to accessibility to base objects. The problem here is how we serialise them to JSON, which currently maintains a blacklist of attributes we don&#8217;t want. Obviously when iOS adds a new accessibility attribute it will get added to the JSON. A much better approach (and the one we would always prefer), is to maintain a whitelist of attributes to serialise.</p>
<p>There have also been comments on HN relating to the fact that there is no need for this middleware if you are properly protecting against mass-assignment. Whilst this is true in part, a fairly normal behaviour when you receive a param you don&#8217;t want to mass-assign is to raise an error, which would result in the same behaviour in the client (i.e broken). Therefore it can be useful to filter the param via middleware whilst clients are updated.</p>
<p>Its maybe worth mentioning that the API already did filter out harmful params (i.e. things that could exploit the rails mass-assignment), and would raise errors on unexpected ones. Therefore a new parameter coming from a client would stop the client from successfully creating an object.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/logicalfriday.wordpress.com/720/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/logicalfriday.wordpress.com/720/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=logicalfriday.com&#038;blog=22779237&#038;post=720&#038;subd=logicalfriday&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://logicalfriday.com/2012/10/03/ios-6-injecting-should_group_accessibility_children-to-post-requests/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7bef7f24d0c9da5537eec0c80b5cc7d8?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">thomaspomfret</media:title>
		</media:content>
	</item>
		<item>
		<title>Rails, callbacks, workers, and the race you never expected to lose</title>
		<link>http://logicalfriday.com/2012/08/21/rails-callbacks-workers-and-the-race-you-never-expected-to-lose/</link>
		<comments>http://logicalfriday.com/2012/08/21/rails-callbacks-workers-and-the-race-you-never-expected-to-lose/#comments</comments>
		<pubDate>Tue, 21 Aug 2012 11:08:49 +0000</pubDate>
		<dc:creator>Phil Nash</dc:creator>
				<category><![CDATA[Back-end development]]></category>
		<category><![CDATA[callbacks]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[workers]]></category>

		<guid isPermaLink="false">http://logicalfriday.com/?p=705</guid>
		<description><![CDATA[Consider a fairly normal pattern in a user model in Rails, sending a welcome email when a user signs up. If you&#8217;re interested in keeping your controller actions quick whilst you do this, you would probably queue the email to be sent later, like this: class User &#60; ActiveRecord::Base after_save :queue_welcome_email, :on =&#62; :create private [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=logicalfriday.com&#038;blog=22779237&#038;post=705&#038;subd=logicalfriday&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Consider a fairly normal pattern in a user model in Rails, sending a welcome email when a user signs up. If you&#8217;re interested in keeping your controller actions quick whilst you do this, you would probably queue the email to be sent later, like this:</p>
<pre><code>class User &lt; ActiveRecord::Base
  
  after_save :queue_welcome_email, :on =&gt; :create
  private
  def queue_welcome_email
    Resque.enqueue(WelcomeEmailJob, self.id)
  end
end</code></pre>
<pre><code>class WelcomeEmailJob
  @queue = :normal

  def self.perform(user_id)
    user = User.find(user_id)
    UserMailer.welcome_email(user).deliver
  end
end</code></pre>
<p>Straightforward, right? You&#8217;d think so, but if you implemented this and ran it in a live system, you would find a small number of <code>ActiveRecord::RecordNotFound</code> errors cropping up in Resque.</p>
<p><span id="more-705"></span></p>
<h3>What&#8217;s going on?</h3>
<p>This has bitten me on more than one occasion, which is why I&#8217;m taking the time to write it down now. The problem is that your eager worker has snatched the job off the queue and tried to process it before your database transaction has completed. So when it calls to the database to find your new record, it won&#8217;t actually be there, even though you said &#8220;after save&#8221;!</p>
<p>So how do we sort this out? Well, since Rails 3 there has been one last callback beyond <code>after_save</code>: <code><a href="http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html">after_commit</a></code>.</p>
<h3>Problem solved, new problems introduced</h3>
<p>So, all we need to do is replace any <code>after_save</code> that places jobs on a queue with <code>after_commit</code>? Sort of, this does actually raise some other problems for us. Firstly, if you are using transactional fixtures, your tests, like the one below, will now fail.</p>
<pre><code>class UserTest &lt; ActiveSupport::TestCase

  def test_should_queue_email_job
    flexmock(Resque).should_receive(:enqueue).once
    User.create(:email =&gt; 'test@test.com')
  end

end</code></pre>
<p>Transactional fixtures stop us having to teardown and recreate our database every test by just running every test within a transaction and rolling back at the end. This presents a problem; if the <code>after_commit</code> callback only runs once the transaction is complete, then it will never run in our test.</p>
<p>To deal with this, you can either give up on transactional fixtures, which will likely make your tests slow down, or, my preference, create tests that avoid transactions purely for this use case.</p>
<pre><code>class UserAfterCommitTest &lt; ActiveSupport::TestCase

  self.use_transactional_fixtures = false

  def test_should_queue_email_job
    flexmock(Resque).should_receive(:enqueue).once
    User.create(:email =&gt; 'test@test.com')
  end

end</code></pre>
<h3>Dirty Attributes</h3>
<p>Our initial example is now solved, we no longer have an issue with the database and the workers racing against each other to save or retrieve our record. There is one other scenario I want to mention here though. Imagine you are using a 3rd party email newsletter service and you need to keep your users&#8217; emails up to date with the service. You might have something like this:</p>
<pre><code>class User &lt; ActiveRecord::Base

  after_save :update_external_email, :if =&gt; :email_changed?

  private

  def update_external_email
    Resque.enqueue(ExternalEmailJob, self.id)
  end
end</code></pre>
<p>We are suffering with the problem we first discussed here. But, if you just change after_save to after_commit you will never update those emails externally. Why? Because by the time the <code>after_commit</code> callback is triggered, the record&#8217;s dirty state has been reset and <code>email_changed?</code> will return false.</p>
<p>Thankfully, the Rails team had thought of this too. Available on every object is a method called <code><a href="http://api.rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-previous_changes">previous_changes</a></code> which contains a hash of attributes that changed the last time the object was saved. Sadly, with this we don&#8217;t get all our convenience methods like <code>#{attribute}_changed?</code> (although we could write them ourselves) this still tells us what happened to the attributes, so we can use <code>after_commit</code> conditionally.</p>
<p>So, to update our example, we can now write:</p>
<pre><code>class User &lt; ActiveRecord::Base

  after_commit :update_external_email, :if =&gt; :email_previously_changed?

  private

  def update_external_email
    Resque.enqueue(ExternalEmailJob, self.id)
  end

  def email_previously_changed?
    previous_changes[:keys].include?('email')
  end
end</code></pre>
<h3>after_commit and previous_changes save the day</h3>
<p>The race condition between database and workers can be hard to spot and it has caught me on more than one occasion. Thankfully, once you realise you are heading for this sort of issue, or once you catch it, these quick changes will sort you out.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/logicalfriday.wordpress.com/705/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/logicalfriday.wordpress.com/705/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=logicalfriday.com&#038;blog=22779237&#038;post=705&#038;subd=logicalfriday&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://logicalfriday.com/2012/08/21/rails-callbacks-workers-and-the-race-you-never-expected-to-lose/feed/</wfw:commentRss>
		<slash:comments>31</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/8ec1383b240b5ba15ffb9743fceb3c0e?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">philnash</media:title>
		</media:content>
	</item>
		<item>
		<title>Cross domain font woes &#8211; part 2</title>
		<link>http://logicalfriday.com/2012/07/04/cross-domain-font-woes-part-2/</link>
		<comments>http://logicalfriday.com/2012/07/04/cross-domain-font-woes-part-2/#comments</comments>
		<pubDate>Wed, 04 Jul 2012 10:00:41 +0000</pubDate>
		<dc:creator>Thomas Pomfret</dc:creator>
				<category><![CDATA[Front-end development]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://logicalfriday.com/?p=680</guid>
		<description><![CDATA[A few months back we looked at issues related to showing custom fonts in firefox (see Cross domain font woes in Firefox). Since then we have also started hosting more and more sites on heroku where you have no control over nginx. Obviously this makes the previously proposed solution hard to implement&#8230;plus who can remember all [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=logicalfriday.com&#038;blog=22779237&#038;post=680&#038;subd=logicalfriday&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>A few months back we looked at issues related to showing custom fonts in firefox (see <a href="http://logicalfriday.com/2012/03/21/cross-domain-font-woes-in-firefox/" title="Cross domain font woes in Firefox">Cross domain font woes in Firefox</a>). Since then we have also started hosting more and more sites on <a href="http://heroku.com">heroku</a> where you have no control over nginx. Obviously this makes the previously proposed solution hard to implement&#8230;plus who can remember all of that config?</p>
<p><span id="more-680"></span></p>
<p>So we&#8217;ve released <a href="http://rubygems.org/gems/rack-access-control-headers" title="rack-access-control-headers">rack-access-control-headers</a> to make things a whole lot easier! This is a simple bit of rack middleware that can be used in any rack app to set the appropriate headers. Getting started is easy:</p>
<p>1, Add the gem to your Gemfile (if using bundler):</p>
<p><code>gem 'rack-access-control-headers'</code></p>
<p>2, Install:</p>
<p><code>bundle</code></p>
<p>3, Insert middleware, in config/application.rb (or specific environment file &#8211; example from rails):</p>
<p><code>config.middleware.insert_before 'ActionDispatch::Static', 'Rack::AccessControlHeaders', /assets/</code></p>
<p>Where /assets/ is a regex of the path you want to inject the headers.</p>
<p>N.b. including ahead of ActionDispatch::Static is important if you&#8217;re running rails.</p>
<p>By default the the allowed origin is set to &#8220;*&#8221;, if you want to lock this down, you can simply supply a second argument:</p>
<p><code>config.middleware.insert_before 'ActionDispatch::Static', 'Rack::AccessControlHeaders', /assets/, 'http://myawesomesite.com'</code></p>
<p>Simple as that! </p>
<p>One last thing to check is that your web server passes through the headers and that your CDN honors them.</p>
<p>Feel free to submit pull requests with any updates or improvements and I&#8217;d love to hear if you are using this.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/logicalfriday.wordpress.com/680/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/logicalfriday.wordpress.com/680/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=logicalfriday.com&#038;blog=22779237&#038;post=680&#038;subd=logicalfriday&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://logicalfriday.com/2012/07/04/cross-domain-font-woes-part-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7bef7f24d0c9da5537eec0c80b5cc7d8?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">thomaspomfret</media:title>
		</media:content>
	</item>
		<item>
		<title>Collabify &#8211; everyone curates the party playlist</title>
		<link>http://logicalfriday.com/2012/05/10/collabify/</link>
		<comments>http://logicalfriday.com/2012/05/10/collabify/#comments</comments>
		<pubDate>Thu, 10 May 2012 12:27:44 +0000</pubDate>
		<dc:creator>Rodreegez</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://logicalfriday.com/?p=671</guid>
		<description><![CDATA[Last night was the first Music/Tech meetup. It went really well and we had a blast. Lots of interesting folks came down, we had a few drinks, we had a good chat. It was fun. Why am I telling you about this on the Logical Friday technical blog? Because the way we decided to play [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=logicalfriday.com&#038;blog=22779237&#038;post=671&#038;subd=logicalfriday&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Last night was the first Music/Tech meetup. It went really well and we had a blast. Lots of interesting folks came down, we had a few drinks, we had a good chat. It was fun. Why am I telling you about this on the Logical Friday technical blog? Because the way we decided to play music is quite interesting.</p>
<p>Because this was the Music/Tech meetup, we had to have music playing, and it had to be done in a needlessly complicated way. To that end, we decided to take a crack at making the playlist selection more egalitarian. Enter Collabify.</p>
<p><span id="more-671"></span></p>
<p><strong>The idea</strong><br />
The idea was simple &#8211; one Spotify playlist, many people adding to it. Now, I appreciate this is already a solved problem &#8211; Spotify has had collaborative playlists for ages. However, we didn&#8217;t want everyone having to have their laptops open or go and mess with the laptop connected to the PA. Instead we made a mobile-optimized web interface that would allow you to search for and add songs, and a Spotify app to grab peoples requests and put them into a playlist.</p>
<p><strong>How it works</strong><br />
Collabify consists of two main parts, the client and the server. I&#8217;ll talk about the server first.</p>
<p>The server is a super simple Sinatra app. It throws up a web page with a search field, accepts the query and uses the Spotify Metadata API to find a list of results. Once the user clicks &#8220;add&#8221; on a result, we save the Artist, Title and URI values into a Redis list as a JSON encoded string. It&#8217;s quick, it&#8217;s easy. It runs on Heroku.</p>
<p>The client is also super simple. Using the Spotify Apps API, we create a playlist in the main Spotify application (terminology here can get confusing). We then make an AJAX call to the server for the JSON stored in Redis. For each item in the list we get back, we instantiate a track and pop it in the playlist. After our initial setup, we run this fetch-instantiate-populate loop every 20 seconds or so, except on these subsequent runs, we trim the results so we only instantiate new additions.</p>
<p><strong>How did it go?</strong><br />
Well! Aside from a little trouble with the venue WiFi, Collabify was a great success. People had fun adding songs to the playlist, Collabify itself proved to be an excellent conversation piece and most importantly nothing crashed!</p>
<p>We projected the client up on the wall so everyone could see what was in the queue. Here is a ropey picture of it in action:</p>
<div class="wp-caption alignnone" style="width: 622px"><img title="Collabify on the big screen" src="http://distilleryimage6.instagram.com/abb5fcca99ff11e180d51231380fcd7e_7.jpg" alt="Collabify on the big screen" width="612" height="612" /><p class="wp-caption-text">Collabify on the big screen</p></div>
<p>For something conceived in the pub and built in a few snatched hours, I think that&#8217;s a pretty good result. Checkout the <a title="Music/Tech meetup playlist on Spotify" href="http://open.spotify.com/user/rodreegez/playlist/5EqkTkPMQdhlTdG2RFi7vU">playlist</a> we made.</p>
<p>Both the <a title="Collabify server on Github" href="https://github.com/philnash/collabify">Collabify server</a> and <a title="Collabify client on GitHub" href="https://github.com/rodreegez/collabify-client">Collabify client</a> are open source and available for you to have a play with. Be warned though it&#8217;s still held together with string and selotape and should not be considered production software in any way, shape or form!</p>
<p>Did you come to the meetup? Did you add tracks? What were your thoughts?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/logicalfriday.wordpress.com/671/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/logicalfriday.wordpress.com/671/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=logicalfriday.com&#038;blog=22779237&#038;post=671&#038;subd=logicalfriday&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://logicalfriday.com/2012/05/10/collabify/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/087f948e082987b362468e2a9aa1e121?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">rodreegez</media:title>
		</media:content>

		<media:content url="http://distilleryimage6.instagram.com/abb5fcca99ff11e180d51231380fcd7e_7.jpg" medium="image">
			<media:title type="html">Collabify on the big screen</media:title>
		</media:content>
	</item>
		<item>
		<title>Finally, a legitimate use for 3D CSS</title>
		<link>http://logicalfriday.com/2012/03/28/finally-a-legitimate-use-for-3d-css/</link>
		<comments>http://logicalfriday.com/2012/03/28/finally-a-legitimate-use-for-3d-css/#comments</comments>
		<pubDate>Wed, 28 Mar 2012 10:47:36 +0000</pubDate>
		<dc:creator>Peter Westendorp</dc:creator>
				<category><![CDATA[Front-end development]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://logicalfriday.com/?p=623</guid>
		<description><![CDATA[Production sites using 3D transforms are still quite rare these days. I think one of the reasons is that people can&#8217;t find a legitimate reason to use 3D Transforms in their sites. Fair enough. Another reason can be that people think the technique isn&#8217;t mature enough yet. Recently I have been working on a website [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=logicalfriday.com&#038;blog=22779237&#038;post=623&#038;subd=logicalfriday&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Production sites using 3D transforms are still quite rare these days. I think one of the reasons is that people can&#8217;t find a legitimate reason to use 3D Transforms in their sites. Fair enough. Another reason can be that people think the technique isn&#8217;t mature enough yet. Recently I have been working on a website that is making use of 3D CSS, and it&#8217;s working!<br />
In this article I want to show you that you can actually use 3D transforms in a production site, and what to expect when you&#8217;re thinking of using it in your site.</p>
<p><span id="more-623"></span></p>
<h3>A brief background</h3>
<p>Every year the folks of <a href="http://mintdigital.com" target="_blank">Mint Digital</a> leave the office behind for a week of <a href="http://weekender.tumblr.com/" target="_blank">WAW</a>; our product development competition.<br />
The brief this year was to launch a business in 4 days. My team decided to make an affordable personalised present. We came up with <a href="http://foldable.me" target="_blank">Foldable.Me</a>; a little customisable cardboard avatar.</p>
<p><a href="http://foldable.me" target="_blank"><img src="http://logicalfriday.files.wordpress.com/2012/03/small.jpg?w=480" alt="A foldable"   class="alignnone size-full wp-image-633" /></a></p>
<p>As the picture above shows, the foldable avatar is 3D. However, when we started developing the customisation tool, the preview of the foldable was all in 2D. After drinking a few of the local ales, my colleague Phil came up with an utterly ridiculous plan. &#8220;Why don&#8217;t we create a 3D preview?&#8221;. He showed me a demo of a 3D box spinning around on his screen. &#8220;Nice&#8221; I thought, &#8220;but that&#8217;s just a box, and also, we only have 4 days!&#8221;.</p>
<p>Somehow though, he persuaded me to give it a try. I was quite surprised that I managed to set up a prototype of the 3D model in less than a day! Everyone was quite happy to see that with some nifty CSS we were able to improve the user experience of our application quite a bit. It was so much more than just a nice 3D visual effect. Our users would now be able to see a <a href="https://developer.mozilla.org/en-US/demos/detail/foldable-3d-avatar" target="_blank">realistic preview</a> of their final product! (<a href="https://developer.mozilla.org/en-US/demos/detail/foldable-3d-avatar" target="_blank">See it in action</a>)</p>
<p>The other nice thing about using this technique was that whilst we were using some cutting-edge technology, we wouldn&#8217;t exclude users with older browsers from our site. Just some extra lines of CSS and we had a nice 2D version of our 3D model.</p>
<p><a href="https://developer.mozilla.org/en-US/demos/detail/foldable-3d-avatar" target="_blank"><img src="http://logicalfriday.files.wordpress.com/2012/03/foldable_avatar_screenshot1.jpg?w=480&#038;h=360" alt="Foldable.me customizer" width="480" height="360" class="alignnone size-full wp-image-636" /></a></p>
<p>Now this may all sound very nice, but we (inevitably) had to deal with some technical issues.</p>
<h3>Faces pressing through</h3>
<p>For example, I learned that the model renders a lot better in most browsers if you <em>explicitly set the backface-visibility to none on every face of your 3D object</em>. This prevents the backface of your cube to press-through the frontface during animations.</p>
<p>However, Chrome had still some render faults during the animations, but <em>setting the z-index for all faces</em> solved that problem. Even though they&#8217;re both webkit browsers, and using the same version of Webkit, the rendering was different in Chrome and Safari. Safari was handling it a lot better than Chrome.</p>
<h3>Anti-alias</h3>
<p>The worst issue I found was the aliasing in Firefox 11. 3D boxes are not anti-aliased at all in Firefox 11. <em>To trigger anti-aliasing, you need to set a transparent outline on all the faces.</em> That outline would, in this case, break the rendering in Webkit browsers. Because it&#8217;s a browser specific issue I had to put in some dirty old browser detection to fix this issue. It doesn&#8217;t feel good, but at least it works!</p>
<p><a href="https://developer.mozilla.org/en-US/demos/detail/foldable-3d-avatar"><img src="http://logicalfriday.files.wordpress.com/2012/03/anti-alias1.png?w=480&#038;h=325" alt="Anti-alias problem" width="480" height="325" class="alignnone size-full wp-image-635" /></a></p>
<h3>Use it!</h3>
<p>As you would have noticed there are a lot of issues that will show up when you&#8217;re using such a new technique. We wanted to use this in a production site. This meant it had to be of a higher quality than we would aim for, when we would be creating a demo. We had to do some proper cross-browser testing. Using 3D Transforms currently means you have to expect the unexpected. Even the rendering in Chrome and Safari can differ a bit. It is some hassle, but please don&#8217;t let this stop you from using 3D Transforms in a production site! It&#8217;s simply too much fun to skip it&#8230;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/logicalfriday.wordpress.com/623/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/logicalfriday.wordpress.com/623/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=logicalfriday.com&#038;blog=22779237&#038;post=623&#038;subd=logicalfriday&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://logicalfriday.com/2012/03/28/finally-a-legitimate-use-for-3d-css/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/f1aaacc7680adff4c7a4aaa12ab73581?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">peterwestendorp</media:title>
		</media:content>

		<media:content url="http://logicalfriday.files.wordpress.com/2012/03/small.jpg" medium="image">
			<media:title type="html">A foldable</media:title>
		</media:content>

		<media:content url="http://logicalfriday.files.wordpress.com/2012/03/foldable_avatar_screenshot1.jpg" medium="image">
			<media:title type="html">Foldable.me customizer</media:title>
		</media:content>

		<media:content url="http://logicalfriday.files.wordpress.com/2012/03/anti-alias1.png" medium="image">
			<media:title type="html">Anti-alias problem</media:title>
		</media:content>
	</item>
		<item>
		<title>Cross domain font woes in Firefox</title>
		<link>http://logicalfriday.com/2012/03/21/cross-domain-font-woes-in-firefox/</link>
		<comments>http://logicalfriday.com/2012/03/21/cross-domain-font-woes-in-firefox/#comments</comments>
		<pubDate>Wed, 21 Mar 2012 12:41:43 +0000</pubDate>
		<dc:creator>Phil Nash</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://logicalfriday.com/?p=612</guid>
		<description><![CDATA[We love using custom fonts with CSS @font-face declarations and have done so on a number of our recent projects. One thing has caught us out on a couple of occasions though. Here&#8217;s the scenario: You&#8217;re building a site, everything is going well with the styling. Your custom font is looking good on your local [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=logicalfriday.com&#038;blog=22779237&#038;post=612&#038;subd=logicalfriday&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="http://mintdigital.com">We</a> love using custom fonts with CSS @font-face declarations and have done so on a number of <a href="http://revolution.channel4.com/" title="New Year Revolution">our</a> <a href="http://foldable.me" title="Foldable.Me">recent</a> <a href="http://littlesticker.com/" title="Little Sticker">projects</a>. One thing has caught us out on a couple of occasions though. Here&#8217;s the scenario:</p>
<p>You&#8217;re building a site, everything is going well with the styling. Your custom font is looking good on your local version of the site, it&#8217;s been checked in staging and looks good there. You launch the site, it looks good everywhere&#8230; except Firefox. Your favourite development browser (well, mine at least, apparently some people like Chrome a lot these days) is no longer showing that lovely font. You can&#8217;t reproduce this on your own machine, everything seems lost.</p>
<p><span id="more-612"></span></p>
<h2>CDNs and subdomains</h2>
<p>When this has happened to us, it has always come down to one thing: for highly trafficked sites we use a <abbr title="Content Delivery Network">CDN</abbr> to serve static assets like CSS, JavaScript and fonts. These files not only come from a different server, they get served from different subdomains (normally &#8220;media#{n}.awesomenewsite.com&#8221; where n is between 0 and 3). The problem: Firefox allows you to request fonts from the same domain but <strong>requires <a href="https://developer.mozilla.org/en/http_access_control">access control headers</a> to be set when requesting them across different domains</strong>.</p>
<h2>Access Control</h2>
<p>So, how do you set these headers? We use <a href="http://nginx.org/">nginx</a> as a web server so we use a block a bit like the following:</p>
<pre><code>location ~* ^/assets/fonts/ {
  gzip_static on;
  expires max;
  add_header Cache-Control public;
  add_header Access-Control-Allow-Origin http://awesomenewsite.com;
}</code></pre>
<p>If you use Apache, you could add an htaccess file in the folder where the font files live with the following in:</p>
<pre><code>&lt;FilesMatch "\.(ttf|otf|eot|woff)$"&gt;
  &lt;IfModule mod_headers.c&gt;
    Header set Access-Control-Allow-Origin "*"
  &lt;/IfModulegt;
&lt;/FilesMatch&gt;</code></pre>
<p>(That snippet thanks to <a href="http://stackoverflow.com/questions/5008944/how-to-add-an-access-control-allow-origin-header#answer-5009126">this StackOverflow answer</a>.)</p>
<p>Rather than setting the requesting domain, you can also set the origin to * to allow any domain to request the resource. It is probably best practice to define the URLs yourself, but as it is only Firefox that respects this header in reality it doesn&#8217;t matter too much.</p>
<h2>Fonts for everyone</h2>
<p>It&#8217;s easy to add the access control headers for these fonts, but also very easy to forget! I hope this can serve as a reminder to all of us, so we can all get fonts right on the web.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/logicalfriday.wordpress.com/612/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/logicalfriday.wordpress.com/612/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=logicalfriday.com&#038;blog=22779237&#038;post=612&#038;subd=logicalfriday&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://logicalfriday.com/2012/03/21/cross-domain-font-woes-in-firefox/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/8ec1383b240b5ba15ffb9743fceb3c0e?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">philnash</media:title>
		</media:content>
	</item>
		<item>
		<title>You fight like a dairy farmer! Some Twitter whimsy with Ruby</title>
		<link>http://logicalfriday.com/2012/03/14/you-fight-like-a-dairy-farmer/</link>
		<comments>http://logicalfriday.com/2012/03/14/you-fight-like-a-dairy-farmer/#comments</comments>
		<pubDate>Wed, 14 Mar 2012 10:36:33 +0000</pubDate>
		<dc:creator>Phil Nash</dc:creator>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[secret of monkey island]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://logicalfriday.com/?p=593</guid>
		<description><![CDATA[When I was a kid I used to love playing The Secret of Monkey Island. I played it on my Commodore Amiga 500 and it came on four 3.5&#8243; floppy disks. Those were the days. My favourite part of the game was the insult sword-fighting, where, instead of strength, a sharp wit was the only [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=logicalfriday.com&#038;blog=22779237&#038;post=593&#038;subd=logicalfriday&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>When I was a kid I used to love playing <a href="http://www.lucasarts.com/games/monkeyisland/">The Secret of Monkey Island</a>. I played it on my Commodore Amiga 500 and it came on four 3.5&#8243; floppy disks. Those were the days.</p>
<p>My favourite part of the game was the <a href="http://miwiki.net/Insult_Swordfighting">insult sword-fighting</a>, where, instead of strength, a sharp wit was the only way to overcome your opponent. The insults range from derogatory (&#8220;You fight like a dairy farmer!&#8221;) to egotistical (&#8220;I got this scar on my face during a mighty struggle!&#8221;) and you take the lead character, Guybrush Threepwood, through a number of fights to  learn them all.</p>
<p>Fast forward to today and with the power of Twitter and a few lines of Ruby we can recreate insult sword fighting for the modern world!</p>
<p><span id="more-593"></span></p>
<p><a href="http://vsrecommendedgames.wikia.com/index.php?title=Adventure_Games&amp;image=Insult-jpg"><img width="480" src="http://images1.wikia.nocookie.net/__cb20100908185027/vsrecommendedgames/images/0/0b/Insult.jpg" /></a></p>
<h2>Inspiration</h2>
<p>I was inspired to create a Twitter bot by a lightning talk from <a href="http://coreyhaines.com/">Corey Haines</a> at RubyConf 2011. He described creating a <a href="https://twitter.com/#!/happiness2_u_7">happiness bot</a> that responds to people saying &#8220;good morning&#8221; (currently in 21 languages!). He created a gem called <a href="https://github.com/coreyhaines/tweetbot">Tweetbot</a> (no relation to the iOS app) based on top of the Twitter streaming API to make this easy for anyone. You don&#8217;t even need to host it anywhere as it works on <a href="http://www.heroku.com/">Heroku</a>.</p>
<p>With both the tools and the inspiration, all it took was finding a bit of time to implement my bot. Eventually, one Friday night, after an evening in the pub, when all ideas seem like good ones, I wrote <a href="https://twitter.com/GuybrushPirate">Guybot</a>. You can see <a href="https://github.com/philnash/guybot">the code on Github</a>, just to show how easy it is to set up. The bot listens for any insult from the game and responds correctly to it.</p>
<h2>Down to battle</h2>
<p>Since writing the code and setting the bot free, the most fun has been watching people interact with it! From <a href="https://twitter.com/Slap_Bet/status/177229873780232193">adulation</a> to <a href="https://twitter.com/search/guybrushpirate">ongoing battles</a>. It&#8217;s also quite funny just to see how often the phrase &#8220;You fight like a dairy farmer&#8221; is tweeted!</p>
<p>It&#8217;s fun creating Twitter bots, and easy with the Tweetbot gem, so if you want to spread happiness like Corey&#8217;s bot, do battle like mine or anything else you can think of, get involved!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/logicalfriday.wordpress.com/593/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/logicalfriday.wordpress.com/593/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=logicalfriday.com&#038;blog=22779237&#038;post=593&#038;subd=logicalfriday&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://logicalfriday.com/2012/03/14/you-fight-like-a-dairy-farmer/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/8ec1383b240b5ba15ffb9743fceb3c0e?s=96&#38;d=http%3A%2F%2F2.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">philnash</media:title>
		</media:content>

		<media:content url="http://images1.wikia.nocookie.net/__cb20100908185027/vsrecommendedgames/images/0/0b/Insult.jpg" medium="image" />
	</item>
		<item>
		<title>-webkit isn&#8217;t breaking the web. The W3C is</title>
		<link>http://logicalfriday.com/2012/02/14/webkit-isnt-breaking-the-web-the-w3c-is/</link>
		<comments>http://logicalfriday.com/2012/02/14/webkit-isnt-breaking-the-web-the-w3c-is/#comments</comments>
		<pubDate>Tue, 14 Feb 2012 13:41:54 +0000</pubDate>
		<dc:creator>Rodreegez</dc:creator>
				<category><![CDATA[Front-end development]]></category>

		<guid isPermaLink="false">http://logicalfriday.com/?p=569</guid>
		<description><![CDATA[In the post Webkit isn&#8217;t breaking the web, you are, Scott Gilbertson intimates that it is the developers that are leading us to a new era of browser-wars by only implementing the -webkit prefixed CSS properties. The notion is that Webkit currently dominates the mobile browser market, so much so that other browser vendors are [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=logicalfriday.com&#038;blog=22779237&#038;post=569&#038;subd=logicalfriday&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>In the post <a href="http://www.webmonkey.com/2012/02/webkit-isnt-breaking-the-web-you-are/" title="Webkit isn't breaking the web, you are">Webkit isn&#8217;t breaking the web, you are</a>, Scott Gilbertson intimates that it is the developers that are leading us to a new era of browser-wars by only implementing the <code>-webkit</code> prefixed CSS properties. The notion is that Webkit currently dominates the mobile browser market, so much so that other browser vendors are considering implementing the <code>-webkit</code> prefix. I view it differently. I place the blame squarely at the feet of the W3C.</p>
<p><span id="more-569"></span></p>
<p>From Scott&#8217;s piece:</p>
<blockquote><p>Vendor prefixes like -webkit and -moz were designed to help web developers by allowing browser makers to implement CSS features before the official standard was published.</p></blockquote>
<p>I propose that the need for vendor prefixes masks the real problem. What are now known as the CSS3 specs, documents still under revision, was first presented to the W3C in <a href="http://en.wikipedia.org/wiki/CSS#CSS3" title="CSS3 Wikipedia article">1999</a>. That&#8217;s thirteen years ago. Thirteen. A child could have been born and started secondary school. You could rob a bank, be convicted and be out on the street in that time [citation needed]. There are over fifty CSS3 specs, of which only three have become recommendations [<a href="http://en.wikipedia.org/wiki/CSS#CSS3" title="CSS Wikipedia article">ibid</a>]. </p>
<p>That vendor prefixes are so widely used is a symptom of the spec being run by an organisation seemingly more interested in talk than in making decisions. Vendor prefixes are supposed to be for experimental features, not features common to modern browsers.</p>
<p>It&#8217;s simple market forces really &#8211; supply and demand. Webkit has supplied an implementation of several features that are in such demand other browser vendors are considering implementing the <code>-webkit</code> prefix themselves. Therefore, I propose these implementations become recomendations, and we drop all vendor prefixes for it. By tightening the loop between experimentation, adoption and acceptance, we fix the web.</p>
<p>For the web to succeed, difficult decisions have to be made. These are decisions about standards and best practices. They cannot be made lightly. But perhaps they can be made more quickly.</p>
<p>&#8212;</p>
<p>Like this post? Vote it up on <a href="http://news.ycombinator.com/item?id=3589915" title="Vote for this post on hacker news">Hacker News</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/logicalfriday.wordpress.com/569/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/logicalfriday.wordpress.com/569/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=logicalfriday.com&#038;blog=22779237&#038;post=569&#038;subd=logicalfriday&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://logicalfriday.com/2012/02/14/webkit-isnt-breaking-the-web-the-w3c-is/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/087f948e082987b362468e2a9aa1e121?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">rodreegez</media:title>
		</media:content>
	</item>
	</channel>
</rss>
