<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>riot.projects is the tumblelog of Aubrey Holland. You can find me on twitter at @riotpolice</description><title>riot.projects</title><generator>Tumblr (3.0; @aubreyholland)</generator><link>http://riotprojects.com/</link><item><title>record_filter adds column comparisons across tables</title><description>&lt;p&gt;I just released version 0.9.14 of record_filter with a spiffy new feature that allows you to compare columns across tables instead of simply comparing columns against your data. Let’s say you have a Blog class that has_many Posts and you want to only get the articles that were created since the last time their publication was updated. Now you can do this:

&lt;pre&gt;&lt;code&gt;Blog.filter do
  having(:posts)
  with(:updated_at).lt(:posts =&gt; :created_at)
end&lt;/code&gt;&lt;/pre&gt;

This came in handy for the world’s nastiest query that I’m working on, and I hope it will help others as well.&lt;/p&gt;</description><link>http://riotprojects.com/post/293929022</link><guid>http://riotprojects.com/post/293929022</guid><pubDate>Mon, 21 Dec 2009 17:08:19 -0500</pubDate></item><item><title>Setting up Kerberos on Snow Leopard</title><description>&lt;p&gt;For some inexplicable reason, the Kerberos tools have been pretty much completely removed in Snow Leopard, in favor of a simple “Ticket Viewer” app that manages tickets but doesn’t help at all with the Kerberos setup. If you don’t have an existing kerberos setup, your only option in the ticket viewer will be “Add Identity” and it will give you this excellent error message when you try to use it:
&lt;pre&gt;&lt;code&gt;Configuration file does not specify default realm&lt;/code&gt;&lt;/pre&gt;
Because they have removed the setup tools, you now need to configure Kerberos yourself by editing the /etc/krb5.conf to add the default domain and configure the various servers. Here’s an example of the config file that we use on our servers:
&lt;pre&gt;&lt;code&gt;[libdefaults]
default_realm = AOL.COM
&lt;br/&gt;
[realms]
AOL.COM = {
kdc = server1
admin_server = admin_server
default_domain = AOL.COM
}&lt;/code&gt;&lt;/pre&gt;

Replace AOL.COM with your realm, replace the various servers with the IP addresses that apply to your setup and add any more kdc servers you need and you should be good to go.&lt;/p&gt;</description><link>http://riotprojects.com/post/230748191</link><guid>http://riotprojects.com/post/230748191</guid><pubDate>Mon, 02 Nov 2009 07:44:04 -0500</pubDate></item><item><title>RecordFilter turns 0.9.8</title><description>&lt;p&gt;&lt;a href="http://aub.github.com/record_filter/"&gt;Record Filter&lt;/a&gt;, everybody’s favorite ruby library for specifying queries in ActiveRecord, has just hit version 0.9.8. This version has some handy improvements for doing distinct queries and aliasing tables in joins, but it in some cases it is not backwards compatible with previous versions. If you are using an earlier version, take note of the &lt;strong&gt;breaking&lt;/strong&gt; changes described here.&lt;/p&gt;

&lt;h3&gt;Distinct&lt;/h3&gt;

&lt;p&gt;Prior to 0.9.8, there was no support for forcing queries to select distinct results. The new version adds a ‘distinct’ method to the DSL to take care of that situation.&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;Blog.filter do
  with(:created_at).greater_than(1.day.ago)
  having(:posts).with(:permalink, nil)
  distinct
end


# SELECT DISTINCT "blogs".* FROM "blogs" 
#  INNER JOIN "posts" AS blogs__posts ON "blogs".id = blogs__posts.blog_id 
#  WHERE (("blogs".created_at &gt; '2009-06-03 14:00:56') 
#  AND (blogs__posts.permalink IS NULL))
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Table aliasing for joins&lt;/h3&gt;

&lt;p&gt;In earlier versions, it was only possible to set a specific alias for a table that was joined with an explicit join. That caused problems in cases where you want to either specify a specific alias with an implicit join or to join against the same association twice. So, this version adds support for an options hash for both types that supports both :alias and :join_type. This is a &lt;strong&gt;breaking&lt;/strong&gt; change from 0.9.7, where join types were specified differently for each method and were required for only one.&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;Blog.filter do
  having(:posts, :join_type =&gt; :left, :alias =&gt; 'posts_1').with(:title, nil)
  having(:posts, :alias =&gt; 'posts_2').with(:title, 'abc')
end


# SELECT DISTINCT "blogs".* FROM "blogs" 
#  LEFT OUTER JOIN "posts" AS posts_1 ON "blogs".id = posts_1.blog_id 
#  INNER JOIN "posts" AS posts_2 ON "blogs".id = posts_2.blog_id 
#  WHERE ((posts_1.title IS NULL) AND (posts_2.title = 'abc'))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In earlier versions, the alias argument was not available and the join_type was passed as the first parameter. For explicit joins, the same options hash is used, which is a change from 0.9.7 where the join type and alias were passed as parameters.&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;Blog.filter do
  join(Post, :join_type =&gt; :left, :alias =&gt; 'da_posts') do
    on(:id =&gt; :blog_id)
    with(:title, 'def')
  end
end


# SELECT DISTINCT "blogs".* FROM "blogs" 
#  LEFT OUTER JOIN "posts" AS da_posts ON "blogs".id = da_posts.blog_id 
#  WHERE (da_posts.title = 'def')
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For both types, :join_type defaults to :inner and :alias defaults to a clever, unique name for the table.&lt;/p&gt;

&lt;h3&gt;Changes to limit&lt;/h3&gt;

&lt;p&gt;This version brings a &lt;strong&gt;breaking&lt;/strong&gt; change to the ‘limit’ method, which was guilty of some ugly argument swapping in the previous version. The method still allows you to specify both a limit and an offset but now makes the offset an optional second argument rather than the first.&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;Comment.filter do
  with(:offensive, true)
  limit(10, 100)
end

# SELECT * FROM "comments" WHERE ("comments".offensive = 't') 
#   LIMIT 10 OFFSET 100
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If anybody has problems with these changes, feel free to get in touch… aubreyholland at gmail dot com&lt;/p&gt;</description><link>http://riotprojects.com/post/118007691</link><guid>http://riotprojects.com/post/118007691</guid><pubDate>Thu, 04 Jun 2009 14:24:04 -0400</pubDate></item><item><title>Ruby 1.8 funkyness with Class.new and inherited</title><description>&lt;p&gt;I just found a bug in Sinatra where this code will fail with the error “can’t dup NilClass”:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;Class.new(Sinatra::Base) do
  get('/') { 'abc' }
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Sinatra uses the ‘inherited’ method to initialize a number of class variables in new subclasses of Sinatra::Base when they are defined. For normal subclassing, this works great because ‘inherited’ is called before the contents of the class are evaluated. When using Class.new, however, it is called &lt;strong&gt;after&lt;/strong&gt; evaluating the class contents, which means that Sinatra will not have had a chance to set up the variables when ‘get’ is called in this example. Apparently Ruby 1.9 has fixed this issue, but we’re still stuck with it in 1.8.&lt;/p&gt;

&lt;p&gt;Run this code and you’ll get:&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;Inherited!
Some method!
Some method!
Inherited!
&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;class Base
  def self.some_method
    puts 'Some method!'
  end

  def self.inherited(subclass)
    puts 'Inherited!'
  end
end
&lt;br/&gt;
class Sub &lt; Base
  some_method
end
&lt;br/&gt;
Class.new(Base) do
  some_method
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It would be lovely if quick fix for doing this in Sinatra was to call ‘reset!’ as the first line of the class definition, but unfortunately because inherited is called after the class contents are evaluated all of your routes will be wiped out.&lt;/p&gt;

&lt;pre&gt;&lt;code class="ruby"&gt;Class.new(Sinatra::Base) do
  reset!
  get('/') { 'abc' }
end
&lt;/code&gt;&lt;/pre&gt;</description><link>http://riotprojects.com/post/114988808</link><guid>http://riotprojects.com/post/114988808</guid><pubDate>Fri, 29 May 2009 16:36:00 -0400</pubDate></item><item><title>I went to the 4th annual Guac Off in Williamsburg on Saturday...</title><description>&lt;img src="http://28.media.tumblr.com/WVs8hZPYlnwujfknuFSgJP6lo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;I went to the 4th annual Guac Off in Williamsburg on Saturday afternoon, where I had the distinct pleasure of trying 17 different guacamoles. A good day generally involves trying one guacamole, so ya know. The weather was perfect, and it was a blast.&lt;/p&gt;</description><link>http://riotprojects.com/post/112776931</link><guid>http://riotprojects.com/post/112776931</guid><pubDate>Mon, 25 May 2009 10:56:00 -0400</pubDate></item><item><title>This woman married me. She seems not to have realized her...</title><description>&lt;img src="http://28.media.tumblr.com/WVs8hZPYlnwuj0asIMnkDs17o1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;This woman married me. She seems not to have realized her mistake yet.&lt;/p&gt;</description><link>http://riotprojects.com/post/112776822</link><guid>http://riotprojects.com/post/112776822</guid><pubDate>Mon, 25 May 2009 10:56:00 -0400</pubDate></item><item><title>Something about the crispness of this really works for me. It...</title><description>&lt;img src="http://29.media.tumblr.com/WVs8hZPYlnwui6hynaMKD4cNo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Something about the crispness of this really works for me. It could also be that it’s a giant picture of guacamole.&lt;/p&gt;</description><link>http://riotprojects.com/post/112776612</link><guid>http://riotprojects.com/post/112776612</guid><pubDate>Mon, 25 May 2009 10:55:00 -0400</pubDate></item><item><title>I just got a new camera and am trying to work on posting photo...</title><description>&lt;img src="http://25.media.tumblr.com/WVs8hZPYlnefqmyuOQZ4EHEgo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;I just got a new camera and am trying to work on posting photo projects up here once a week or so. Project #1: something that I couldn’t have gotten with my little point and shoot. In this case, the same depth of field affect that every newbie photographer probably does 1000 times a day.&lt;/p&gt;</description><link>http://riotprojects.com/post/106817349</link><guid>http://riotprojects.com/post/106817349</guid><pubDate>Tue, 12 May 2009 13:42:00 -0400</pubDate></item><item><title>Simple Rails performance analysis</title><description>&lt;p&gt;Working on fixing performance problems in our rails app, I often find myself interested in simple performance metrics, like the number of queries that are performed, the slowest partials, and the slowest queries. These things are all there in both the output from script/server and the rails log, so it seems that a lightweight tool ought to be all that’s required to see what’s going on. I recently wrote a &lt;a href="http://gist.github.com/48054"&gt;simple script&lt;/a&gt; to do just that. All you need to do is download the script and then pipe the output of the rails log into it:

&lt;pre&gt;&lt;code&gt;script/server | log_analyzer.rb

tail -f log/development.log | log_analyzer.rb&lt;/code&gt;&lt;/pre&gt;

This will give you the standard output plus some interesting facts like these:

&lt;pre&gt;&lt;code&gt;Top five partials:
global/_header - 1.01129 - 35%
global/_navigation - 0.73292 - 25%
global/_navigation_sub_menu - 0.60205 - 21%
global/_most_popular - 0.3204 - 11%
posts/_post - 0.28982 - 10%
&lt;br/&gt;
Top five selects by type:
Type: Post Count: 59 Time: 0.020275 Percent: 0%
Type: Article Count: 51 Time: 0.017761 Percent: 0%
Type: Section Count: 1 Time: 0.01623 Percent: 0%
Type: Tag Count: 23 Time: 0.009717 Percent: 0%
Type: Place Count: 17 Time: 0.00725 Percent: 0%
&lt;br/&gt;
Top five selects by count:
Type: Post Count: 59 Time: 0.020275 Percent: 0%
Type: Article Count: 51 Time: 0.017761 Percent: 0%
Type: Section Count: 23 Time: 0.009717 Percent: 0%
Type: Tag Count: 17 Time: 0.00725 Percent: 0%
Type: Place Count: 16 Time: 0.005853 Percent: 0%&lt;/code&gt;&lt;/pre&gt;

By the way, if your output looks like this, your app is slow.&lt;/p&gt;</description><link>http://riotprojects.com/post/106810485</link><guid>http://riotprojects.com/post/106810485</guid><pubDate>Tue, 12 May 2009 13:23:00 -0400</pubDate></item><item><title>ActiveRecord observers in gems/plugins</title><description>&lt;p&gt;I’ve recently been working on a &lt;a href="http://github.com/aub/cache_advance/tree/master"&gt;caching tool&lt;/a&gt; for Rails that has a declarative API for invalidating caches when objects of specific types are changed. The idea is that we should be able to tell the caching system that specific types of caches are automatically invalidated for a given type:

&lt;pre&gt;&lt;code class="ruby"&gt;cache_config.article_cache :expiration_types =&gt; [ :article ]
&lt;/code&gt;&lt;/pre&gt;

This requires that the gem be able to set up an ActiveRecord observer in order to do the requested invalidations. There are a couple of non-obvious challenges here that seem worth working through. The first issue is that the observer needs to be added to the list of ActiveRecord::Base.observers in order to be fired correctly. One option is to require the user to set this up in their environment file or in an initializer, the standard places for this sort of thing, but that pretty much ruins any sense of transparency you might have had. A better option is to set it up yourself in the rails initializer of your gem. The three big lessons here are:

&lt;ol&gt;&lt;li&gt;If you create a rails/init.rb file in your gem, it will be executed as the rails app is initialized.&lt;/li&gt;
&lt;li&gt;When this file is executed, the Rails::Configuration object used in environment.rb is in scope, and&lt;/li&gt;
&lt;li&gt;The Rails::Configuration object has some lovely hook methods you can use to initialize your observer&lt;/li&gt;
&lt;/ol&gt;&lt;pre&gt;&lt;code class="ruby"&gt;config.after_initialize do
  ActiveRecord::Base.observers &lt;&lt; CacheAdvance::ActiveRecordSweeper
end&lt;/code&gt;&lt;/pre&gt;

OK, so we’re all set, right? Unfortunately, your awesome observer is just about to fail miserably in development mode. The problem there is that while the observer in your gem isn’t going to get reloaded with every request, the models that it’s observing will, and that will break the observer/observed relationship. The solution is to force the observer to restate what it observes, and fortunately Rails has a callback to help us do just that:

&lt;pre&gt;&lt;code class="ruby"&gt;config.after_initialize do
  if config.action_controller.perform_caching
    ActiveRecord::Base.observers &lt;&lt; CacheAdvance::ActiveRecordSweeper

    # In development mode, the models we observe get reloaded with each request. Using
    # this hook allows us to reload the observer relationships each time as well.
    ActionController::Dispatcher.to_prepare(:cache_advance_reload) do
      CacheAdvance::ActiveRecordSweeper.instance.reload_sweeper
    end
  end
end&lt;/code&gt;&lt;/pre&gt;

The to_prepare method in ActionController::Dispatcher allows you to specify a block that will get called before the first request in production mode and before each request in development mode, and we can use that block to restate the observer relationships:

&lt;pre&gt;&lt;code class="ruby"&gt;class ActiveRecordSweeper &lt; ::ActiveRecord::Observer
  def reload_sweeper
    observed_classes.each do |klass| 
      klass.name.constantize.add_observer(self)
    end
  end
end&lt;/code&gt;&lt;/pre&gt;

And with that you should be observing like a champ.&lt;/p&gt;</description><link>http://riotprojects.com/post/106808946</link><guid>http://riotprojects.com/post/106808946</guid><pubDate>Tue, 12 May 2009 13:19:00 -0400</pubDate></item></channel></rss>

