<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>
Matthew Rudy Jacobs
see me swim
Github
see some of my code
WorkingWithRails
see me working with rails
</description><title>RudyGems</title><generator>Tumblr (3.0; @rudygems)</generator><link>http://rudygems.com/</link><item><title>Rails 3 doesn't allow "open" as a Named Scope</title><description>&lt;p&gt;Rails 3 has involved rewriting pretty much the whole codebase,&lt;/p&gt;
&lt;p&gt;Rails 3 gives off the fragrance of a coherent, cohesive framework.&lt;/p&gt;
&lt;p&gt;But this one kind of annoys me.&lt;/p&gt;
&lt;blockquote&gt;/Users/matthew/.bundle/ruby/1.8/bundler/gems/rails-16a5e918a06649ffac24fd5873b875daf66212ad-master/activerecord/lib/active_record/named_scope.rb:104:in `scope’: Cannot define scope :open because AbcDef.open method already exists. (ArgumentError)&lt;/blockquote&gt;
&lt;p&gt;So, in Rails 3, when defining a named scope, we can’t override an existing method.&lt;/p&gt;
&lt;p&gt;This all makes sense, we don’t want to inadvertently break anything (although I’d hope your test would catch such a thing)&lt;/p&gt;
&lt;p&gt;But unfortunately, every object in Ruby has an “open” method… so “open” suddenly is off the market for named scopes… bummer&lt;/p&gt;
&lt;p&gt;I spent most of day trying to sort this out… writing a patch… trying to convince people to apply it… but the rails core guys wouldn’t budge.&lt;/p&gt;
&lt;p&gt;So here’s a quick hack I put in an initializer&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;# config/initializers/allow_open_as_a_named_scope.rb
require 'active_record'
class ActiveRecord::Base
  class &lt;&lt; self
    alias :_open :open
    undef_method :open
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we’re done…&lt;/p&gt;
&lt;p&gt;Kind of annoying though. I use “open” all the time, because it makes sense&lt;/p&gt;
&lt;p&gt;I’d prefer it if active record just made a logger.warn, and let me make my own decisions&lt;/p&gt;
&lt;p&gt;&lt;a href="http://github.com/matthewrudy/rude-rails/tree/make_named_scopes_warn_rather_than_raise"&gt;My Fork of rails&lt;/a&gt;, &lt;a href="http://github.com/matthewrudy/rails3-doesnt-allow-open-as-a-named-scope"&gt;My Example of the bug&lt;/a&gt;, &lt;a href="http://gist.github.com/306330"&gt;My Undef_Method hack&lt;/a&gt;&lt;/p&gt;</description><link>http://rudygems.com/post/420138339</link><guid>http://rudygems.com/post/420138339</guid><pubDate>Mon, 01 Mar 2010 17:21:37 +0000</pubDate><category>ruby</category><category>rails</category><category>rails3</category><category>activerecord</category><category>named_scope</category></item><item><title>Securing CruiseControl.rb on Nginx</title><description>&lt;p&gt;CruiseControl is great&lt;/p&gt;
&lt;p&gt;Quick and easy to setup&lt;/p&gt;
&lt;p&gt;But takes a few minutes to work out how to secure it.&lt;/p&gt;

&lt;p&gt;we start cruise;&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;cruise@MerlotBuild:~/cruisecontrol.rb$ ./cruise start -d
=&gt; Booting Mongrel
=&gt; Rails 2.3.2 application starting on &lt;a href="http://0.0.0.0:3333"&gt;http://0.0.0.0:3333&lt;/a&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Going directly by IP &lt;a href="http://94.102.144.37:3333"&gt;http://94.102.144.37:3333&lt;/a&gt; we get our cruise install.&lt;/p&gt;
&lt;p&gt;But that’s not good enough, we need to secure it from the outside world&lt;/p&gt;
&lt;p&gt;In Nginx we do this;&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;server {
  listen 80;
  server_name cruise.matthewrudy.com;
  
  auth_basic "Access";
  auth_basic_user_file /opt/nginx/conf/htpasswd;

  location / {
    proxy_pass http://localhost:3333;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we’re almost done&lt;/p&gt;
&lt;p&gt;Except &lt;a href="http://94.102.144.37:3333"&gt;http://94.102.144.37:3333&lt;/a&gt; still works, as mongrel allows requests from any host name&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;cruise@MerlotBuild:~/cruisecontrol.rb$ ./cruise start -d -b 127.0.0.1
=&gt; Booting Mongrel
=&gt; Rails 2.3.2 application starting on &lt;a href="http://127.0.0.1:3333"&gt;http://127.0.0.1:3333&lt;/a&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Does the job… home… secure… safe?&lt;/p&gt;</description><link>http://rudygems.com/post/379741413</link><guid>http://rudygems.com/post/379741413</guid><pubDate>Tue, 09 Feb 2010 10:02:40 +0000</pubDate><category>nginx cruisecontrol</category></item><item><title>How big is my MySQL database?</title><description>&lt;pre&gt;&lt;code class="mysql"&gt;mysql&gt; SELECT table_schema,&lt;br/&gt;  sum(data_length) / 1024 / 1024 "data",&lt;br/&gt;  sum(index_length) / 1024 / 1024 "index",&lt;br/&gt;  sum( data_length + index_length ) / 1024 / 1024 "total"&lt;br/&gt;FROM information_schema.TABLES&lt;br/&gt;GROUP BY table_schema \G;&lt;br/&gt;&lt;br/&gt;*************************** 1. row ***************************&lt;br/&gt;table_schema: aardvarks_development&lt;br/&gt;        data: 5297.32812500&lt;br/&gt;       index: 4407.93750000&lt;br/&gt;       total: 9705.26562500&lt;br/&gt;*************************** 2. row ***************************&lt;br/&gt;table_schema: aardvarks_test&lt;br/&gt;        data: 0.09375000&lt;br/&gt;       index: 0.25000000&lt;br/&gt;       total: 0.34375000&lt;br/&gt;*************************** 3. row ***************************&lt;br/&gt;table_schema: badgers_development&lt;br/&gt;        data: 13.59375000&lt;br/&gt;       index: 16.60937500&lt;br/&gt;       total: 30.2031250&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;as you can see, aardvarks_developpment is almost taking up 10gig&lt;/p&gt;
&lt;p&gt;if we only care about “test” databases, we can add a condition on “table_schema”&lt;/p&gt;
&lt;pre&gt;&lt;code class="mysql"&gt;mysql&gt; SELECT table_schema,&lt;br/&gt;  sum(data_length) / 1024 / 1024 "data",&lt;br/&gt;  sum(index_length) / 1024 / 1024 "index",&lt;br/&gt;  sum( data_length + index_length ) / 1024 / 1024 "total"&lt;br/&gt;FROM information_schema.TABLES&lt;br/&gt;WHERE table_schema like "%_test"&lt;br/&gt;GROUP BY table_schema \G;&lt;br/&gt;&lt;br/&gt;*************************** 1. row ***************************&lt;br/&gt;table_schema: aardvarks_test&lt;br/&gt;        data: 0.09375000&lt;br/&gt;       index: 0.25000000&lt;br/&gt;       total: 0.3437500&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Boom!&lt;/p&gt;
&lt;p&gt;(credit to &lt;a title="Paul Butcher" href="http://www.paulbutcher.com"&gt;Paul Butcher&lt;/a&gt; for the query)&lt;/p&gt;</description><link>http://rudygems.com/post/206608569</link><guid>http://rudygems.com/post/206608569</guid><pubDate>Wed, 07 Oct 2009 11:33:00 +0100</pubDate><category>mysql</category></item><item><title>Updating RubyGems on Ubuntu 9.04</title><description>&lt;p&gt;I don’t know how many times I’ve had to do this.&lt;/p&gt;
&lt;p&gt;But every time I install Ubuntu again, I get this;&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;matthew@Rudyness:~$ sudo gem update --system&lt;br/&gt;ERROR: While executing gem ... (RuntimeError)&lt;br/&gt;gem update --system is disabled on Debian. RubyGems can be updated using the official Debian repositories by aptitude or apt-get.&lt;br/&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The simple fix;&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;matthew@Rudyness:~$ sudo gem install rubygems-update&lt;br/&gt;Successfully installed rubygems-update-1.3.5&lt;br/&gt;1 gem installed&lt;br/&gt;Installing ri documentation for rubygems-update-1.3.5...&lt;br/&gt;Installing RDoc documentation for rubygems-update-1.3.5...&lt;br/&gt;matthew@Rudyness:~$ sudo /var/lib/gems/1.8/bin/update_rubygems &lt;br/&gt;Installing RubyGems 1.3.5&lt;br/&gt;RubyGems 1.3.5 installed&lt;br/&gt;&lt;br/&gt;RubyGems installed the following executables:&lt;br/&gt;	/usr/bin/gem1.8&lt;br/&gt;&lt;br/&gt;matthew@Rudyness:~$ gem --version&lt;br/&gt;1.3.5&lt;br/&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From now on you can “sudo gem update —system” as much as you want.&lt;/p&gt;
&lt;p&gt;Sweetness.&lt;/p&gt;</description><link>http://rudygems.com/post/164224985</link><guid>http://rudygems.com/post/164224985</guid><pubDate>Sun, 16 Aug 2009 17:23:50 +0100</pubDate><category>ruby</category><category>gems</category><category>rubygems</category><category>ubuntu</category><category>install</category><category>update</category></item><item><title>Installing Ruby 1.9.1 on Ubuntu 9.04</title><description>&lt;p&gt;Now, I’m upset that Jaunty Jackalope doesn’t ship with ruby 1.9.1 as default,&lt;br/&gt; and the packaged version is only 1.9.0.&lt;/p&gt;
&lt;p&gt;So we’re going to have to build it from source.&lt;/p&gt;
&lt;p&gt;And because we’re all progressive people, we’re not even going to worry about suffixing the executables with `1.9` &lt;i&gt;I can’t be bothered to type `&lt;code&gt;gem1.9`&lt;/code&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;The dependencies are simple;&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;sudo apt-get install build-essential libssl-dev libreadline5 libreadline5-dev zlib1g zlib1g-dev&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then the usual process…&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;mkdir ~/src &amp;&amp; cd ~/src
wget &lt;a href="ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.1-p0.tar.gz"&gt;ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.1-p0.tar.gz&lt;/a&gt;
tar -xvf ruby-1.9.1-p0.tar.gz
cd ruby-1.9.1-p0
./configure
make
make test
sudo make install&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And to get rails working properly&lt;/p&gt;
&lt;pre&gt;&lt;code class="bash"&gt;sudo gem update --system
sudo gem install rails

# and to get sqlite3 working properly
sudo apt-get install sqlite3 libsqlite3-dev
sudo gem install sqlite3-ruby&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Done.&lt;/p&gt;
&lt;p&gt;&lt;i&gt;I’ll add to this if I notice any problems&lt;/i&gt;&lt;/p&gt;</description><link>http://rudygems.com/post/99075288</link><guid>http://rudygems.com/post/99075288</guid><pubDate>Thu, 23 Apr 2009 00:24:00 +0100</pubDate><category>ruby</category><category>ubuntu</category><category>1.9.1</category><category>source</category><category>install</category></item><item><title>Ruby 1.9 becoming the standard?</title><description>&lt;p&gt;There’s a lot of talk recently about pushing the Ruby Community onto Ruby 1.9.&lt;/p&gt;
&lt;p&gt;Now that’s cool, the more people using 1.9 the quicker the issues will get ironed out&lt;/p&gt;
&lt;p&gt;(people need to be spurred into fixing their libraries)&lt;/p&gt;
&lt;p&gt;But there is one thing standing in the way of 1.9 being adopted by the whole community, &lt;b&gt;Default Packages&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Mac OSX comes with 1.8.6&lt;/b&gt; as standard, &lt;b&gt;Ubuntu 8.10 comes with 1.8.7&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;Whitney Houston said “the children are our future”, and that’s exactly who we need to start using 1.9 right from the word go.&lt;/p&gt;
&lt;p&gt;With &lt;b&gt;Ubuntu 9.04 (Jaunty Jackalope) and OSX Snow Leopard on their way out&lt;/b&gt; soon, surely if they adopted 1.9 as the default, we’d be on the road to success.&lt;/p&gt;
&lt;p&gt;However, maybe that’s not going to happen.&lt;/p&gt;
&lt;p&gt;A quick look at &lt;a href="http://packages.ubuntu.com/jaunty/interpreters/ruby"&gt;the packages of Jaunty Jackalope&lt;/a&gt; and you’ll see&lt;/p&gt;
&lt;blockquote&gt;This package is a dependency package, which depends on Debian’s default Ruby version (currently 1.8.x).&lt;/blockquote&gt;
&lt;p&gt;So I guess this thing’s not going to get fixed soon.&lt;/p&gt;</description><link>http://rudygems.com/post/90433520</link><guid>http://rudygems.com/post/90433520</guid><pubDate>Fri, 27 Mar 2009 20:11:19 +0000</pubDate></item><item><title>Expire eTAGs when you redeploy</title><description>&lt;p&gt;Rails 2.2’s eTAG functionality is great.&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;def show&lt;br/&gt;  @article = Article.find(params[:id])&lt;br/&gt;  if stale_record(@article)&lt;br/&gt;    # do something expensive&lt;br/&gt;  end&lt;br/&gt;end&lt;br/&gt;&lt;br/&gt;protected&lt;br/&gt;&lt;br/&gt;  def stale_record?(record)&lt;br/&gt;    fresh_when(:etag =&gt; [current_user, record], :last_modified =&gt; record.updated_at.utc)&lt;br/&gt;    !request.fresh?(response)&lt;br/&gt;  end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;“304 NOT MODIFIED” all around!&lt;/p&gt;
&lt;p&gt;But this determines freshness based on just the record.&lt;br/&gt; If I deploy a new version of the “show” template eTAG-compliant browsers won’t refresh.&lt;/p&gt;
&lt;p&gt;I could build my own way of handling this inside “stale_record?”&lt;br/&gt; But Rails already has a method for dealing with this.&lt;/p&gt;
&lt;p&gt;All cache keys are generated through the following code.&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;if ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]&lt;br/&gt;  expanded_cache_key &lt;&lt; "#{ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]}/"&lt;br/&gt;end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So what does it mean to be the RAILS_APP_VERSION?&lt;br/&gt; Well, I’m going to mis-use it, and say “it’s the current version of our app”&lt;/p&gt;
&lt;p&gt;And Capistrano already gives this to us… it gives us /current/REVISION!!!&lt;/p&gt;
&lt;p&gt;Perfect!&lt;/p&gt;
&lt;p&gt;A quick “/config/initializers/capified_etags.rb” later&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;app_version_path = File.join(Rails.root, "REVISION")&lt;br/&gt;if File.exist?(app_version_path)&lt;br/&gt;  ENV["RAILS_APP_VERSION"] = File.open(app_version_path).read.strip&lt;br/&gt;end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nice.&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Let me know if there are any other approaches out there.&lt;/i&gt;&lt;/p&gt;</description><link>http://rudygems.com/post/71647725</link><guid>http://rudygems.com/post/71647725</guid><pubDate>Mon, 19 Jan 2009 23:02:00 +0000</pubDate><category>304</category><category>caching</category><category>etag</category><category>git</category><category>rails</category><category>ruby</category><category>capistrano</category></item><item><title>setting up a simple git server</title><description>&lt;p&gt;On the internet you’ll see people talking about &lt;a title="Gitosis is a heavyweight git server, apparently." href="http://twitter.com/craigwebster/statuses/1032437697"&gt;Gitosis&lt;/a&gt;, or just giving over all of their git requirements to &lt;a title="Yeah, I love my github." href="http://github.com/matthewrudy"&gt;github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Github is great, but if you just want to do a small personal project, with an off-site repository, go set up your &lt;a title="I use Tagadab for my virtual server. Just a 256meg, but it does very little work." href="http://tagadab.com/virtual-private-servers"&gt;VPS&lt;/a&gt; as your main git server.&lt;/p&gt;
&lt;p&gt;Here’s how you do it.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;h3&gt;create a “git” user&lt;/h3&gt;
&lt;pre&gt;&lt;code class="bash"&gt;sudo adduser git&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;add your ssh keys to that user&lt;/h3&gt;
&lt;pre&gt;&lt;code class="bash"&gt;ssh-copy-id git@my.com&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;create a “bare” repository on your server&lt;/h3&gt;
&lt;pre&gt;&lt;code class="bash"&gt;mkdir myRepo.git
git --bare init&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;add this as a remote source&lt;/h3&gt;
&lt;pre&gt;&lt;code class="bash"&gt;git remote add origin git@my.com:myRepo.git
git push origin master&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;BOOM! that is literally all it takes!&lt;/p&gt;
&lt;p&gt;&lt;i&gt;Thanks to &lt;a title="commonthread.com is where I learnt this all." href="http://blog.commonthread.com/2008/4/14/setting-up-a-git-server"&gt;CommonThread&lt;/a&gt; for his tutorial on doing this.&lt;/i&gt;&lt;/p&gt;</description><link>http://rudygems.com/post/65970932</link><guid>http://rudygems.com/post/65970932</guid><pubDate>Sat, 20 Dec 2008 23:36:00 +0000</pubDate><category>git</category><category>server</category><category>sysadmin</category><category>tutorial</category></item><item><title>Rails + Rack Middleware</title><description>&lt;p&gt;Rails just released &lt;a title="Josh Peek's commit on Github" href="http://github.com/rails/rails/commit/8c3a54366435eebc2c8aa63b63e1349ce74a7b38"&gt;Metal&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;Giving us a great framework to build custom Rack processors alongside our application.&lt;/p&gt;
&lt;p&gt;Check out &lt;a title="Metal as a Rails micro framework" href="http://soylentfoo.jnewland.com/articles/2008/12/16/rails-metal-a-micro-framework-with-the-power-of-rails-m"&gt;this great article&lt;/a&gt; over at Soylent Foo.&lt;/p&gt;
&lt;p&gt;Recently we had a problem where Microsoft Office was somehow issuing OPTIONS request to our site.&lt;/p&gt;
&lt;p&gt;This was blowing up our RESTful controllers that weren’t invited to the OPTIONS party.&lt;/p&gt;
&lt;p&gt;We played with Apache rewrites based on REQUEST_METHOD,&lt;/p&gt;
&lt;p&gt;but ultimately, we wasted a lot of time fighting against Rails and routing exceptions, blahblahblah.&lt;/p&gt;
&lt;p&gt;But now Rails is running off Rack we can deal with it the correct way.&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class OptionsCatcher &lt; Rails::Rack::Metal
  def call(env)
    if env["REQUEST_METHOD"] =~ /OPTIONS/i
      [403, {"Content-Type" =&gt; "text/html"}, "OPTIONS requests are forbidden"]
    else
      super
    end
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;B00M!&lt;/p&gt;
&lt;p&gt;Now this is technically just middleware, and should be declared with a&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;config.middleware.use OptionsCatcher&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and in lib/options_catcher.rb&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class OptionsMiddleware
  def initialize(app)
    @app = app
  end
  
  def call(env)
    if env["REQUEST_METHOD"] =~ /OPTIONS/i
      [403, {"Content-Type" =&gt; "text/html"}, "OPTIONS requests are forbidden"]
    else
      @app.call(env)
    end
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;but doing it as a Metal makes sense, and is easier than remembering the structure of middleware each time&lt;/p&gt;
&lt;p&gt;But there seems to be a problem at the moment with this.&lt;/p&gt;
&lt;p&gt;Will try and get a proper Metal working shortly.&lt;/p&gt;</description><link>http://rudygems.com/post/65344295</link><guid>http://rudygems.com/post/65344295</guid><pubDate>Wed, 17 Dec 2008 12:09:00 +0000</pubDate><category>ruby</category><category>rails</category><category>rack</category><category>metal</category></item><item><title>has_one_accessor</title><description>&lt;p&gt;&lt;a href="http://github.com/matthewrudy/has_one_accessor"&gt;HasOneAccessor&lt;/a&gt; is a plugin for ActiveRecord that solves the problem of having associations that act like a attribute.&lt;/p&gt;
&lt;p&gt;Perhaps only a few users have an openid, so it doesn’t make sense to add an :open_id_url column to your :users table.&lt;/p&gt;
&lt;p&gt;Instead you create a new model OpenId&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class OpenId &lt; ActiveRecord::Base
  belong_to :user
end

class User &lt; ActiveRecord::Base
  has_one :open_id

  def open_id_url
    self.open_id &amp;&amp; self.open_id.url
  end

  def open_id_url=(value)
    if value.blank?
      self.open_id &amp;&amp; self.open_id = nil
    else
      self.open_id || self.build_open_id
      self.open_id.url = value
    end
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, that’s not too bad. But maybe you didn’t have time to clean it up.&lt;/p&gt;
&lt;p&gt;Maybe you deal with it in your controller.&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;def update
  if params[:open_id_url] &amp;&amp; params[:open_id_url].present?
    @user.open_id || @user.build_open_id
    @user.open_id.url = params[:open_id_url]
  end
  ...
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, that’s all fine.&lt;/p&gt;
&lt;p&gt;But we all want to make these things easier.&lt;/p&gt;
&lt;p&gt;We all want to cast as much code aside.&lt;/p&gt;
&lt;p&gt;ConventionOverConfiguration and all that.&lt;/p&gt;
&lt;p&gt;Enter &lt;a href="http://github.com/matthewrudy/has_one_accessor"&gt;has_one_accessor&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class OpenId &lt; ActiveRecord::Base
  belong_to :user
end

class User &lt; ActiveRecord::Base
  has_one :open_id
  has_one_accessor :open_id, :url, :allow_blank =&gt; false
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This takes away all the code,&lt;/p&gt;
&lt;p&gt;This takes care of building a record if there wasn’t one, of only saving it when you save the User.&lt;/p&gt;
&lt;p&gt;It even kills the association if the value is :blank? (if you pass in :allow_blank =&gt; false).&lt;/p&gt;
&lt;p&gt;B00m, h34dsh0t?&lt;/p&gt;</description><link>http://rudygems.com/post/62315783</link><guid>http://rudygems.com/post/62315783</guid><pubDate>Sun, 30 Nov 2008 22:51:18 +0000</pubDate></item><item><title>SolrQuery - build your solr queries dynamically in Ruby</title><description>&lt;p&gt;I’ve been using ActsAsSolr for about 6 months.&lt;/p&gt;
&lt;p&gt;And at work I developed some code to make SOLR queries work a bit like the conditions in ActiveRecord.&lt;/p&gt;
&lt;p&gt;Check out my library at Github. &lt;a href="http://github.com/matthewrudy/solr_query"&gt;http://github.com/matthewrudy/solr_query&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;SolrQuery.build(:keyword =&gt; "Feather duster"
=&gt; "feather duster"&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;SolrQuery.build(:keyword =&gt; "clean",
                :organisation =&gt; [organisation1, organisation2])&lt;br/&gt;=&gt; "clean AND organisation:(275 OR 6534)"&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Wicked!&lt;/p&gt;
&lt;p&gt;Check out the readme for more examples.&lt;/p&gt;</description><link>http://rudygems.com/post/60175045</link><guid>http://rudygems.com/post/60175045</guid><pubDate>Mon, 17 Nov 2008 21:22:00 +0000</pubDate><category>ruby</category><category>solr</category><category>fulltext</category><category>search</category><category>github</category><category>plugin</category></item><item><title>UID problems across a shared mount?</title><description>&lt;p&gt;We just moved to new Ubuntu servers.&lt;/p&gt;
&lt;p&gt;We use file-column (with some modifications) to deal with our file uploads.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;deploy@jgp-web01:/var/www/oursite$ ls -l public/uploaded_file/file_name/000/000/051/585/ &lt;br/&gt;total 4&lt;br/&gt;-rw-r--r-- 1 gerhard www-data 2670 2008-11-15 05:09 MatthewJacobsCV.txt&lt;br/&gt;&lt;br/&gt;&lt;/code&gt;&lt;code&gt;deploy@jgp-web02:/var/www/oursite$ ls -l public/uploaded_file/file_name/000/000/051/585/ &lt;br/&gt;total 4&lt;br/&gt;-rw-r--r-- 1 deploy www-data 2670 2008-11-15 05:09 MatthewJacobsCV.txt&lt;br/&gt;&lt;/code&gt;&lt;br/&gt;&lt;/pre&gt;
&lt;p&gt;If you look carefully, you’ll see one is owned by “deploy” and the other by “gerhard”.&lt;/p&gt;
&lt;p&gt;These are mounted by NFS, shared across the two computers.&lt;/p&gt;
&lt;p&gt;So these are actually the same file, but with different permissions on each.&lt;/p&gt;
&lt;p&gt;A quick use of the “id” command confirmed this;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;deploy@jgp-web01:~$ id deploy&lt;br/&gt;uid=1004(deploy) gid=33(www-data) groups=33(www-data),1005(aspire)&lt;br/&gt;&lt;br/&gt;deploy@jgp-web02:~$ id deploy&lt;br/&gt;uid=1002(deploy) gid=33(www-data) groups=33(www-data),1003(aspire)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The answer is;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@jgp-web01:~# usermod -u 10000 deploy&lt;br/&gt;&lt;br/&gt;root@jgp-web02:~# usermod -u 10000 deploy&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;boom!&lt;/p&gt;
&lt;p&gt;Now this is resolved, but you’ll have to chown all the existing files, back to `deploy`, else they’ll still be attached to the old uid.&lt;/p&gt;</description><link>http://rudygems.com/post/59819490</link><guid>http://rudygems.com/post/59819490</guid><pubDate>Sat, 15 Nov 2008 14:26:00 +0000</pubDate><category>uniq</category><category>linux</category><category>sysadmin</category><category>uid</category><category>usermod</category></item><item><title>"svn switch —relocate svn://oldserver svn+ssh://newserver"</title><description>“svn switch —relocate svn://oldserver svn+ssh://newserver”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;need to move your svn repository?&lt;/em&gt;</description><link>http://rudygems.com/post/59309952</link><guid>http://rudygems.com/post/59309952</guid><pubDate>Wed, 12 Nov 2008 12:21:17 +0000</pubDate><category>svn</category><category>subversion</category><category>tip</category></item><item><title>Welcome home DHH!
After a long time, it seems DHH is back,...</title><description>&lt;img src="http://30.media.tumblr.com/QHTuMQiIgfrzksinPCEzcWtOo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;h2&gt;&lt;a href="http://github.com/rails/rails/commits/"&gt;Welcome home DHH!&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;After a long time, it seems DHH is back, actively commiting to rails.&lt;/p&gt;
&lt;p&gt;Getting ready for 2.2 to be released, he’s committed 20 times in the past week.&lt;/p&gt;
&lt;p&gt;It’s nice to see.&lt;/p&gt;</description><link>http://rudygems.com/post/57452448</link><guid>http://rudygems.com/post/57452448</guid><pubDate>Sat, 01 Nov 2008 16:01:00 +0000</pubDate><category>rails</category><category>random</category><category>dhh</category><category>github</category></item><item><title>Google App Engine to support Ruby?</title><description>&lt;p&gt;A &lt;a href="http://googleappengine.blogspot.com/2008/10/google-app-engine-roadmap-now-published.html"&gt;recent post&lt;/a&gt; on the Google App Engine blog refers to;&lt;/p&gt;
&lt;blockquote&gt;“Support for a new runtime language”&lt;/blockquote&gt;
&lt;p&gt;That’s got to be ruby…&lt;/p&gt;
&lt;p&gt;Imagine a bespoke &lt;a href="http://deadprogrammersociety.blogspot.com/2007/10/sinatra-ruby-web-framework-and-why-it.html"&gt;Sinatra&lt;/a&gt;-style minimal framework, with &lt;a href="http://datamapper.org/doku.php"&gt;DataMapper&lt;/a&gt; bindings to the &lt;a href="http://sites.google.com/site/io/under-the-covers-of-the-google-app-engine-datastore"&gt;Google DataStore&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;No doubt it’ll be pretty quick to make it work with Merb as well.&lt;/p&gt;
&lt;p&gt;AWESOME.&lt;/p&gt;
&lt;p&gt;Why did google never reply to my job application asking to work on it?&lt;/p&gt;
&lt;p&gt;&lt;i&gt;(if you haven’t seen the videos from last years Google IO, then they’re well worth watching - &lt;a href="http://sites.google.com/site/io/"&gt;here&lt;/a&gt;)&lt;/i&gt;&lt;/p&gt;</description><link>http://rudygems.com/post/56110000</link><guid>http://rudygems.com/post/56110000</guid><pubDate>Fri, 24 Oct 2008 11:51:00 +0100</pubDate><category>google</category><category>app engine</category><category>big table</category></item><item><title>"it’s hard enough to push out a great idea,
even if you thought of it,
and have spent years..."</title><description>“&lt;p&gt;it’s hard enough to push out a great idea,&lt;br/&gt;
even if you thought of it,&lt;br/&gt;
and have spent years thinking about it.&lt;/p&gt;

&lt;p&gt;If a potential investor is going to take the time, money, and bother to steal your idea,&lt;br/&gt;
then someone else is going to buy it from you&lt;br/&gt;
before they have a chance.&lt;/p&gt;”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;me, talking to &lt;a href="http://clanbase.ggl.com/personinfo.php?pid=2872454"&gt;Stephen Strudwick&lt;/a&gt; about startups, already in Beta, being too scared to pitch to investors!&lt;/em&gt;</description><link>http://rudygems.com/post/55333580</link><guid>http://rudygems.com/post/55333580</guid><pubDate>Sun, 19 Oct 2008 22:06:00 +0100</pubDate></item><item><title>Rendering layouts that live in /public?</title><description>&lt;p&gt;At work we have the following concept.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;a “site” has a subset of our content&lt;/li&gt;
&lt;li&gt;a “site” has a url - eg. “oursite.com/stickers” or “stickersNOTvicars.com”&lt;/li&gt;
&lt;li&gt;a “site” can have its own customised layout, or fall back to the default one&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;How does this work in code?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;site.articles (pretty simple)&lt;/li&gt;
&lt;li&gt;a whole load of “route filters” that match the incoming host&lt;/li&gt;
&lt;li&gt;the code I’m writing about&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So, historically we did&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;class ApplicationController
  layout :determine_layout
  def determine_layout
    if File.exists?("#{Rails.root}/public/sites/#{@site.id}/application.rhtml")
      "../../public/sites/#{@site.id}/application"
    else
      "site_default"
    end
  end
end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This was a hack, and it breaks with Rails 2.1.1, so after a day or so playing with the internals of ActionView I discovered this;&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;append_view_path("#{Rails.root}/public/sites")&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And it works!&lt;/p&gt;
&lt;p&gt;We just need to set;&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;"#{@site.id}/application"&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;as our layout, and we’re away.&lt;/p&gt;
&lt;p&gt;Site-specific layouts that live in /public!&lt;/p&gt;</description><link>http://rudygems.com/post/54730156</link><guid>http://rudygems.com/post/54730156</guid><pubDate>Wed, 15 Oct 2008 21:16:20 +0100</pubDate><category>code</category><category>ruby</category><category>public</category><category>actionview</category><category>layouts</category><category>templates</category></item><item><title>"I didn’t get drunk enough to try the Goggles. Next time!"</title><description>“I didn’t get drunk enough to try the Goggles. Next time!”</description><link>http://rudygems.com/post/54582962</link><guid>http://rudygems.com/post/54582962</guid><pubDate>Wed, 15 Oct 2008 00:13:48 +0100</pubDate></item><item><title> Google Goggles are good enough for me?
On Monday its the LRUG...</title><description>&lt;img src="http://26.media.tumblr.com/QHTuMQiIgezb1yu3JSsxPrrjo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;h2&gt;&lt;a href="http://www.youtube.com/watch?v=5kMi9tvuuZY"&gt; Google Goggles are good enough for me?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;On Monday its the &lt;a href="http://lrug.org/"&gt;LRUG&lt;/a&gt; quiz.&lt;/p&gt;
&lt;p&gt;Can Google’s entry into drunken embarassment prevention really hold out against my mathematical skills?&lt;/p&gt;
&lt;p&gt;Am I just too elite?&lt;/p&gt;
&lt;p&gt;At level 5 (the hardest) we still get sums like “6x9”!&lt;/p&gt;
&lt;p&gt;Does my mathematical ability really drop that much?&lt;/p&gt;
&lt;p&gt;We’ll see tomorrow!&lt;/p&gt;</description><link>http://rudygems.com/post/54206773</link><guid>http://rudygems.com/post/54206773</guid><pubDate>Sun, 12 Oct 2008 15:17:00 +0100</pubDate><category>lrug</category><category>google</category><category>goggles</category><category>drink</category><category>alcohol</category><category>gmail</category></item><item><title>What would happen if you ripped out your Db server?</title><description>&lt;p&gt;Does your application and architecture really have failover?&lt;/p&gt;
&lt;p&gt;If I broke into your datacentre, ripped out, and hid one of your servers, what would happen?&lt;/p&gt;
&lt;p&gt;Is your architecture the biggest hurdle to scaling your web app?&lt;/p&gt;
&lt;p&gt;&lt;a href="http://events.carsonified.com/fowa/2008/london/highlights/blaine-cook-joe-stump/"&gt;Blain Cook and Joe Stump not talking about Twitter’s scaling issues.&lt;/a&gt;&lt;/p&gt;</description><link>http://rudygems.com/post/54093260</link><guid>http://rudygems.com/post/54093260</guid><pubDate>Sat, 11 Oct 2008 16:42:14 +0100</pubDate></item></channel></rss>
