<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DEQCQH8ycSp7ImA9WhRVEkU.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989</id><updated>2012-01-11T04:52:41.199-08:00</updated><category term="action_pack" /><category term="fixtures" /><category term="ruby on rails" /><category term="active_record" /><category term="css" /><category term="javascript" /><category term="mysql" /><category term="prototype" /><category term="action_view" /><title>Strictly Untyped</title><subtitle type="html">Pragmatic Rails in an Idiomatic World</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.strictlyuntyped.com/" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>25</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/strictlyuntyped/WqEA" /><feedburner:info uri="strictlyuntyped/wqea" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DkcMQ38_cCp7ImA9Wx9QEkk.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-106215753835165342</id><published>2010-12-24T18:16:00.000-08:00</published><updated>2010-12-24T18:28:02.148-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-24T18:28:02.148-08:00</app:edited><title>New Ruby 1.9 hash syntax</title><content type="html">&lt;div style="font-family:verdana"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Ruby 1.9 supports a new hash syntax. It looks like this:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;script src="https://gist.github.com/754624.js?file=hash.rb"&gt;&lt;/script&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;This only works if the key is a symbol. I don't recommend using it if the hash has both symbols and other types of objects, because you end up mixing the new syntax with the "old".&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Textmate Snippet&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;If you're using Textmate, change your &lt;span style="font-style:italic;"&gt;Hash Pair - :key =&gt; "value"&lt;/span&gt; snippet to the following:&lt;/span&gt;&lt;pre&gt;${1:key}: ${2:"${3:value}"}${4:, }&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-106215753835165342?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/HRYukagPPGk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/106215753835165342/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=106215753835165342" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/106215753835165342?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/106215753835165342?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/HRYukagPPGk/new-ruby-19-hash-syntax.html" title="New Ruby 1.9 hash syntax" /><author><name>matthuhiggins</name><uri>http://www.blogger.com/profile/06084411057663300780</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2010/12/new-ruby-19-hash-syntax.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0IHSHY-eCp7ImA9WxFWFUw.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-2895844239257737886</id><published>2010-06-02T14:51:00.000-07:00</published><updated>2010-06-02T14:52:19.850-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-02T14:52:19.850-07:00</app:edited><title>Tweaking on Rails 3.0: #4 Object#presence</title><content type="html">&lt;div style="font-family:verdana"&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Object#presence is new to &lt;span style="font-style: italic;"&gt;object/blank.rb&lt;/span&gt; in &lt;span style="font-style: italic;"&gt;ActiveSupport&lt;/span&gt; (&lt;a href="http://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/object/blank.rb#L35"&gt;View source&lt;/a&gt;). It simply returns self if self.present? is true, otherwise it returns nil. This works great for blank strings and empty arrays:&lt;br /&gt;
&lt;br /&gt;
Let's give our blog posts a default title if a blank one is provided:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="http://gist.github.com/423046.js?file=gistfile1.builder"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Now let's refactor it with Object#&lt;span style="font-weight:bold"&gt;presence&lt;/span&gt;&lt;/span&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="http://gist.github.com/423052.js?file=gistfile1.builder"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;How cute.&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-2895844239257737886?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/hhupGK1wrM4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/2895844239257737886/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=2895844239257737886" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/2895844239257737886?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/2895844239257737886?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/hhupGK1wrM4/tweaking-on-rails-30-4-objectpresence.html" title="Tweaking on Rails 3.0: #4 Object#presence" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2010/06/tweaking-on-rails-30-4-objectpresence.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0IMR3w8fip7ImA9WxFWE0o.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-624730890255183658</id><published>2010-05-28T10:41:00.000-07:00</published><updated>2010-05-31T22:53:06.276-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-31T22:53:06.276-07:00</app:edited><title>Tweaking on Rails 3.0: #3 class_attribute</title><content type="html">&lt;div style="font-family:verdana"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;We all know that class variables in Ruby don't work well with inheritance. For this reason, &lt;span style="font-style: italic"&gt;ActiveSupport&lt;/span&gt; originally added &lt;span style="font-weight: bold"&gt;class_inheritable_accessor&lt;/span&gt; (&lt;a href="http://github.com/rails/rails/blob/2-3-stable/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb"&gt;view source&lt;/a&gt;). The method works by using the &lt;span style="font-style: italic"&gt;Class.inherited&lt;/span&gt; callback, and copying attributes down to subclasses. This was basically a hack. It failed to work correctly if the parent's accessor was written to after the inherited classes were defined, and it's wasteful to copy attributes to every inheriting class.&lt;br /&gt;&lt;br /&gt;Along comes &lt;span style="font-weight: bold"&gt;class_attribute&lt;/span&gt; (&lt;a href="http://github.com/rails/rails/blob/v3.0.0.beta.3/activesupport/lib/active_support/core_ext/class/attribute.rb"&gt;view source&lt;/a&gt;). It works by defining the class accessor methods on the class's singleton class. The technique is described in more detail by &lt;a href="http://railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/"&gt;a railstips.org article&lt;/a&gt;. The win is that we're getting true inheritance and expected behavior.&lt;br /&gt;&lt;br /&gt;How do you improve your code in Rails 3? Simply replace the text &lt;span style="font-weight: bold"&gt;class_inheritable_accessor&lt;/span&gt; with &lt;span style="font-weight: bold"&gt;class_attribute&lt;/span&gt;!&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-624730890255183658?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/pl-kjdMF4Ac" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/624730890255183658/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=624730890255183658" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/624730890255183658?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/624730890255183658?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/pl-kjdMF4Ac/tweaking-on-rails-30-3-classattribute.html" title="Tweaking on Rails 3.0: #3 class_attribute" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2010/05/tweaking-on-rails-30-3-classattribute.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4HQ348eCp7ImA9WxFWEE4.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-2967563150019873948</id><published>2010-05-28T00:09:00.000-07:00</published><updated>2010-05-28T00:48:52.070-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-28T00:48:52.070-07:00</app:edited><title>Tweaking on Rails 3.0: #2 ActiveSupport::Concern</title><content type="html">&lt;div style="font-family:verdana"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Unless you've been writing your Ruby code in a cave, deep within uninhabited mountains, you have probably seen and written a Ruby module. And it probably went something like this:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/416873.js?file=gistfile1.builder"&gt;&lt;/script&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Including this into a &lt;span style="font-weight: bold"&gt;User&lt;/span&gt; model gives us &lt;span style="font-style: italic"&gt;User.awesome&lt;/span&gt;, &lt;span style="font-style: italic"&gt;User.make_everyone_awesome&lt;/span&gt;, and &lt;span style="font-style: italic"&gt;User#awesome?&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Before getting into ActiveSupport::Concern, you shouldn't be defining the InstanceMethods module and explicitly including it. Remove it now, based on &lt;a href="http://yehudakatz.com/2009/11/12/better-ruby-idioms/"&gt;reasons explained by Yehuda Katz&lt;/a&gt;. I only provide it in this example for criticism.&lt;br /&gt;&lt;br /&gt;In Rails 3, extend your module with &lt;span style="font-weight: bold"&gt;ActiveSupport::Concern&lt;/span&gt;. This gives you two things:&lt;ul&gt;&lt;li&gt;The including class is automatically extended with the ClassMethods module. No more klass.extend(ClassMethods).&lt;/li&gt;&lt;li&gt;You get a new method called "included", which provides a terser way to define the idiomatic "self.include(base)" method.&lt;/li&gt;&lt;/ul&gt;. This is best described by a refactoring of the above example:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/416885.js?file=gistfile1.builder"&gt;&lt;/script&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;As an aside, the &lt;span style="font-weight: bold"&gt;Awesomeness&lt;/span&gt; module should definitely go into Rails core, but they keep ignoring my requests.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-2967563150019873948?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/dd1ZgTGVjzQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/2967563150019873948/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=2967563150019873948" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/2967563150019873948?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/2967563150019873948?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/dd1ZgTGVjzQ/tweaking-on-rails-30-2.html" title="Tweaking on Rails 3.0: #2 ActiveSupport::Concern" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2010/05/tweaking-on-rails-30-2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0AGSXgyfSp7ImA9WxFWEE4.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-8630989649328458023</id><published>2010-05-27T23:50:00.001-07:00</published><updated>2010-05-28T00:28:48.695-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-28T00:28:48.695-07:00</app:edited><title>Tweaking on Rails 3.0: #1 Callback Blocks</title><content type="html">&lt;div style="font-family:verdana"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;There are plenty of articles about the big changes in Rails 3, so I feel motivated to comment on the small ones.&lt;br /&gt;You might be familiar with using a block with a callback. Let's define an article model for our awesome new blogging software. It defines a default title for a newly created &lt;span style="font-weight: bold"&gt;article&lt;/span&gt;:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/416856.js?file=gistfile1.builder"&gt;&lt;/script&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Notice that we must pass the new &lt;span style="font-weight: bold"&gt;article&lt;/span&gt; to the block. In Rails 3, the block is evaluated within the scope of the new instance, so we can change it to look like this:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/416862.js?file=gistfile1.txt"&gt;&lt;/script&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Extremely minor, but I find myself using block callbacks more often because of it.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-8630989649328458023?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/gPVbuHEv2kM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/8630989649328458023/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=8630989649328458023" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/8630989649328458023?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/8630989649328458023?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/gPVbuHEv2kM/tweaking-on-rails-30-1-callback-blocks.html" title="Tweaking on Rails 3.0: #1 Callback Blocks" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2010/05/tweaking-on-rails-30-1-callback-blocks.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0MNRHg_fSp7ImA9WxNSGUs.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-5225287423149945949</id><published>2009-09-02T22:46:00.000-07:00</published><updated>2009-09-03T00:04:55.645-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-03T00:04:55.645-07:00</app:edited><title>Foreigner comes full circle</title><content type="html">&lt;div style="font-family:verdana"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;After actively developing multiple Rails projects over the last three years, I've learned when to not fight the framework, and I've also learned when it's appropriate to roll up your sleeves and write some Ruby code. I've stopped using &lt;a href="http://github.com/drnic/composite_primary_keys/tree/master"&gt;composite primary keys&lt;/a&gt;, I've stopped attempting to &lt;a href="http://www.strictlyuntyped.com/2008/08/activerecord-can-haz-namespaces.html"&gt;namespace models&lt;/a&gt;, I always use the default "id" for a primary key, the list goes on.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;One thing my mind has not changed on is using foreign keys. I use them, and I've finally completed &lt;a style="font-weight: bold" href="http://github.com/matthuhiggins/foreigner/tree/master"&gt;Foreigner&lt;/a&gt;, a foreign key migration library that meets my initial requirements:&lt;ul&gt;&lt;li&gt;Do not change existing behavior of the application&lt;/li&gt;&lt;li&gt;Perform a no-op when the adapter does not support foreign keys&lt;/li&gt;&lt;li&gt;Follow similar API as 'add_index'&lt;/li&gt;&lt;li&gt;Dump foreign keys into schema.rb&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Do not change existing behavior of the application&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;I found numerous existing foreign key plugins that attempted to &lt;span style="font-style: italic"&gt;automagically&lt;/span&gt; add foreign keys. For example, &lt;a href="http://github.com/harukizaemon/foreign_key_migrations/tree/master"&gt;automatically adding foreign keys based on column names&lt;/a&gt;, or &lt;a href="http://agilewebdevelopment.com/plugins/foreign_key_associations"&gt;automatically adding associations to active record models base on foreign keys in the database&lt;/a&gt;. I believe both of these are mistakes. Automatically adding foreign keys changes existing migrations, and always seems to break things. Automatically creating active record associations puts too much guesswork into play. There's a difference between using foreign keys to enforce integrity (good), and using foreign keys to change the behavior of the application (bad).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Lastly, I thought long and hard about whether calls to &lt;span style="font-weight: bold"&gt;t.references&lt;/span&gt; should automatically add a foreign key. I finally resolved on not doing this, and compromised by adding a new &lt;span style="font-style: italic"&gt;:foreign_key&lt;/span&gt; option. For example:&lt;/span&gt;&lt;pre&gt;change_table :comments do |t|&lt;br /&gt;  t.references :author, :foreign_key =&gt; true&lt;br /&gt;end&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Perform a no-op when the adapter does not support foreign keys&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;While this does not help me, it is required to support adapters such as sqlite3. The &lt;a href="http://github.com/matthuhiggins/foreigner/blob/904986112df534c4ae01e1da51e12876df60741b/lib/foreigner/connection_adapters/abstract/schema_statements.rb"&gt;AbstractAdapter&lt;/a&gt; implements all necessary methods with a no-op. With Foreigner installed, you can develop with sqlite3 and run production with MySql.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Follow similar API as 'add_index'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Adding foreign keys isn't much different than adding indexes, and everyone is familiar with using &lt;span style="font-weight: bold"&gt;add_index&lt;/span&gt;. You &lt;span style="font-weight: bold"&gt;add_foreign_key&lt;/span&gt;, &lt;span style="font-weight: bold"&gt;remove_foreign_key&lt;/span&gt; and can even use &lt;span style="font-weight: bold"&gt;change_table&lt;/span&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Dump foreign keys into schema.rb&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;The final feature I added to Foreigner is dumping foreign keys to schema.rb, so that you can avoid using the SQL structure. Similar to how indexes are added to schema.rb, Foreigner inspects the database and determines the foreign keys.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: 130%"&gt;In conclusion...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;There's been a lot of discussion in the past about whether or not you should be using foreign keys. This shows to me is that there is a large group of people who probably want this available out of the box with Rails. The library was designed to not affect those who don't want them; the primary purpose in doing so was to show that everyone can have it their own way. My next step is turning this into a gem.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Get the source: &lt;a href="http://github.com/matthuhiggins/foreigner/tree/master"&gt;http://github.com/matthuhiggins/foreigner/tree/master&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-5225287423149945949?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/e5RsSa0WwtM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/5225287423149945949/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=5225287423149945949" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/5225287423149945949?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/5225287423149945949?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/e5RsSa0WwtM/foreigner-comes-full-circle.html" title="Foreigner comes full circle" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>8</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2009/09/foreigner-comes-full-circle.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkIMQnw_eip7ImA9WxVaGUw.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-7978518195073526509</id><published>2009-04-16T14:26:00.000-07:00</published><updated>2009-04-16T14:49:43.242-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-16T14:49:43.242-07:00</app:edited><title>A Foreign Key migration plugin for Rails</title><content type="html">&lt;div style="font-family:verdana"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;I use foreign keys in my Rails projects, and they work great. There was a point in time where Rails tests did not work well when using foreign keys, but those days are long gone. I've been hand rolling foreign key migrations for quite some time, and decided to write a plugin that covers most of my needs. This resulted in &lt;span style="font-weight: bold"&gt;Foreigner&lt;/span&gt;, which is now available at &lt;a href="http://github.com/matthuhiggins/foreigner/tree/master"&gt;http://github.com/matthuhiggins/foreigner/tree/master&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;One of my goals was to follow the API for &lt;span style="font-style: italic"&gt;add_index&lt;/span&gt; and &lt;span style="font-style: italic"&gt;remove_index&lt;/span&gt;. Another goal was to make sure migrations did not break when run against adapters that do not support foreign keys. The API simply no-ops by default, and only supported adapters perform the operation. (MySql is currently the only implemented adapter.)&lt;br /&gt;&lt;br /&gt;You should be able to add most of your foreign keys with following (See the &lt;a href="http://github.com/matthuhiggins/foreigner/tree/master#readme"&gt;Readme&lt;/a&gt; for more details.)&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;add_foreign_key(:comments, :posts)&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;If you drank the Rails lemonade and don't think foreign keys are necessary, you're correct. They're not necessary, they are a nice to have.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-7978518195073526509?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/s6cDQGRy-fU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/7978518195073526509/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=7978518195073526509" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/7978518195073526509?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/7978518195073526509?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/s6cDQGRy-fU/foreign-key-migration-plugin-for-rails.html" title="A Foreign Key migration plugin for Rails" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2009/04/foreign-key-migration-plugin-for-rails.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkAHQX8_eSp7ImA9WxVUFko.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-5885467596397755341</id><published>2009-03-21T15:42:00.000-07:00</published><updated>2009-03-21T16:38:50.141-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-21T16:38:50.141-07:00</app:edited><title>A Survey of URL Sharing Debris</title><content type="html">&lt;div style="font-family:verdana"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;As a loyal follower of &lt;a href="http://www.edwardtufte.com/tufte/"&gt;Tufte&lt;/a&gt;, I believe in removing all unnecessary junk and debris from the visual design of a website. (The layout for this blog is a preselected template from Blogger; don't hold it against me). I'm going to point out a trend I'm noticing everywhere, and you will either start being irritated by it, or disagree with me. I call it &lt;span style="font-weight: bold"&gt;URL Sharing Debris&lt;/span&gt;, and it is best described with examples. I surfed to random websites to collect a few samples.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;huffingtonpost.com&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://4.bp.blogspot.com/_6FnnKREfVl8/ScVwfvKmAeI/AAAAAAAAABg/BORE0-V19oc/s400/huffingtonpost.com.png" /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Here's your classic example. Since it's too hard to copy and paste a URL, the user is provided with approximately 8-10 icons to share the URL.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;indecisionforever.com&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://3.bp.blogspot.com/_6FnnKREfVl8/ScVwz4U4biI/AAAAAAAAABo/CqWWJpJwvZM/s400/indecisionforever.com.png" /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt; At least they realize the icons detract from the content and gray them out.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;www.dailymail.co.uk&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://4.bp.blogspot.com/_6FnnKREfVl8/ScVw0NlU-XI/AAAAAAAAAB4/YquUz_BAaFc/s400/www.dailymail.co.uk.png" /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Since most users won't know what the icons mean, this example adds labels.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;youtube.com&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://2.bp.blogspot.com/_6FnnKREfVl8/ScVw0WXNPBI/AAAAAAAAACA/axFioWK55Mk/s400/youtube.com.png" /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;More space is wasted on the sharing section than on the video control. Am I the only one who knows how to copy and paste the URL displayed in my browser?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;failblog.org&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://3.bp.blogspot.com/_6FnnKREfVl8/ScVtmjaJ_4I/AAAAAAAAABY/v2R57wh6f30/s400/failblog.org.png" /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Finally, a site that makes fun of the sharing links.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;scm.jadeferret.com&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://3.bp.blogspot.com/_6FnnKREfVl8/ScVw0KFLCBI/AAAAAAAAABw/Ywf-MztI0SE/s400/scm.jadeferret.com.png" /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;In my quest to find the worst offender, I came across the above winner.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Final words&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;I think a lot of site developers responsible for this are simply copying popular sites who started this trend. Putting a Digg button on your site does not make it popular. It needs to be popular in the first place.&lt;br /&gt;&lt;br /&gt;It is difficult to fit content on a page. It is difficult to design clean aesthetics. I believe this fad will eventually die, and join the graveyard with &lt;a href="http://en.wikipedia.org/wiki/Webring"&gt;webrings&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-5885467596397755341?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/xuyvEe3Ayro" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/5885467596397755341/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=5885467596397755341" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/5885467596397755341?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/5885467596397755341?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/xuyvEe3Ayro/survey-of-url-sharing-debris.html" title="A Survey of URL Sharing Debris" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_6FnnKREfVl8/ScVwfvKmAeI/AAAAAAAAABg/BORE0-V19oc/s72-c/huffingtonpost.com.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2009/03/survey-of-url-sharing-debris.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkEEQns-fCp7ImA9WxVaGU8.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-3497929914284402963</id><published>2009-03-18T19:54:00.001-07:00</published><updated>2009-04-16T15:23:23.554-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-16T15:23:23.554-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="css" /><title>5 new CSS features you can use if you drop IE6</title><content type="html">&lt;div style="font-family:verdana"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;It is time for most sites to drop IE6, especially for projects that are just getting started. If you do make this choice, it is important to realize that there are some new CSS features that you can begin using, and some old habits worth dropping. While there are many sites that describe CSS bugs in IE6, I found no websites that describe working examples to improve your CSS and HTML if you simply drop support for it.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Here are 5 examples from my own project, &lt;a href="http://www.haikuvillage.com"&gt;Haiku Village&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;1. Attribute Selectors&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;You can use attribute selectors for any arbitrary attribute, but I have used it exclusively for form elements.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;style&amp;gt;&lt;br /&gt;input[type="submit"] {&lt;br /&gt;  margin-top: 5px;&lt;br /&gt;}&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;input type="submit" value="Save" /&amp;gt;&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;This will help you delete those arbitrary class names you made up to select certain types of inputs.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;2. Multiple Classes on a Single Element&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;This is best described with an example:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;style&amp;gt;&lt;br /&gt;.icon {&lt;br /&gt;  background: transparent url(/images/icons.png) no-repeat scroll 0 0;&lt;br /&gt;  padding: 2px 0 0 20px;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.icon.trash {&lt;br /&gt;  background-position: 0 -80px;    &lt;br /&gt;}&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;span class="icon trash"&amp;gt;Delete&amp;lt;/span&amp;gt;&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;With IE6, you either needed to make a class name of "icon-delete", or nest one element inside of the other.&lt;/span&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;3. Sibling Selectors&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;There are many ways to use sibling selectors. My most recent use of them is to add borders between the list items in a sub menu:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;style&amp;gt;&lt;br /&gt;ul.menu li + li {&lt;br /&gt;  border-left: 1px dotted #DADADA;&lt;br /&gt;  padding-left: 8px;&lt;br /&gt;}&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;Normally, you would need to introduce a "first" or "last" class name to make the borders only appear between items, and not on the outside.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;3. Child Selectors&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;If you know that a certain style should &lt;span style="font-weight: bold;"&gt;only&lt;/span&gt; apply immediately within an element, then simply insert a "&gt;" into your stylesheets:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;style&amp;gt;&lt;br /&gt;ul.menu &amp;gt; li {&lt;br /&gt;    float: left;&lt;br /&gt;    margin-right: 7px;&lt;br /&gt;    padding: 3px 0 1px;&lt;br /&gt;  }&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;This will ensure that other list items within this list item do not receive the style. It also prevents the necessity to define a new class name, such as "menu-item"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;4. Use :hover on any element&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;I started web development in 1995, and until recently, I never considered using the :hover meta selector for anything besides the "a" tag. Remove this from your mind, because it is no longer the case. I use :hover to expose some icons when you mouse over a haiku:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;style&amp;gt;&lt;br /&gt;.haiku .actions {&lt;br /&gt;  visibility: hidden;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.haiku:hover .actions&lt;br /&gt;  :visibility visible&lt;br /&gt;}&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;Most of us have probably worked around this by either introducing an arbitrary "a" element with an "href='#'", or by adding a class name during a 'mouseover' event.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;5. New properties available&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;There are plenty of new properties that you can start using. The most significant are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-style: italic"&gt;min-width/min-height&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic"&gt;max-width/max-height&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-style: italic"&gt;background-attachment&lt;/span&gt; - You can use a value of 'fixed'&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;There are hacks to make all of these work in IE6, but that's the point: You should stop the hacking. Also, did I mention transparent PNGs?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-3497929914284402963?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/FnUEb3X4uts" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/3497929914284402963/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=3497929914284402963" title="13 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/3497929914284402963?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/3497929914284402963?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/FnUEb3X4uts/5-new-css-features-you-can-use-if-you_18.html" title="5 new CSS features you can use if you drop IE6" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>13</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2009/03/5-new-css-features-you-can-use-if-you_18.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMFRn09fCp7ImA9Wx5aE08.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-7058858962358531913</id><published>2009-01-18T22:40:00.000-08:00</published><updated>2010-11-09T09:06:57.364-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-09T09:06:57.364-08:00</app:edited><title>A matter of style...</title><content type="html">&lt;div style="font-family:verdana"&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;I've seen plenty of code examples that show how to set the current user or subdomain to a variable. For example:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/669396.js?file=before.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;However, I prefer this way:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/669396.js?file=after.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;With this technique, I always use the &lt;span style="font-weight: bold;"&gt;current_user&lt;/span&gt; method to determine the current user, and never reference the &lt;span style="font-weight: bold;"&gt;@current_user&lt;/span&gt; variable. If an action doesn't need to know the current_user, no time is wasted to set it.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-7058858962358531913?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/AIupBX81w80" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/7058858962358531913/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=7058858962358531913" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/7058858962358531913?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/7058858962358531913?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/AIupBX81w80/matter-of-style.html" title="A matter of style..." /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2009/01/matter-of-style.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUEARnY_cSp7ImA9Wx9TGEw.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-5130586814545070201</id><published>2008-11-26T16:16:00.001-08:00</published><updated>2010-11-26T15:20:47.849-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-26T15:20:47.849-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="action_view" /><category scheme="http://www.blogger.com/atom/ns#" term="action_pack" /><title>I killed ApplicationController</title><content type="html">&lt;div style="font-family:verdana"&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;For the longest time, &lt;a href="http://blog.jayfields.com/2008/01/rails-changing-applicationrb-to.html"&gt;developers have asked&lt;/a&gt; for &lt;span style="font-style: italic"&gt;application.rb&lt;/span&gt; to be renamed to &lt;span style="font-style: italic"&gt;application_controller.rb&lt;/span&gt;. This is finally fixed in &lt;a href="http://github.com/rails/rails/commit/fcce1f17eaf9993b0210fe8e2a8117b61a1f0f69"&gt;RailsEdge&lt;/a&gt;, and there's even a &lt;a href="http://afreshcup.com/2008/11/17/rails-2x-the-death-of-applicationrb/"&gt;Death of Application.rb&lt;/a&gt; blog posting about it.&lt;br /&gt;
&lt;br /&gt;
That's great, but none of this affects me. Why? Because ApplicationController always annoyed me, so I killed it.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;Life without ApplicationController&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;You might ask, "how do you survive without this loving, parental figure; the &lt;span style="font-style: italic"&gt;ApplicationController&lt;/span&gt;?" Because my parent is &lt;span style="font-style: italic"&gt;ActionController::Base&lt;/span&gt;, in the same way that most of your models inherit from &lt;span style="font-style: italic"&gt;ActiveRecord::Base&lt;/span&gt;. Can you tell me why your models don't inherit from an arbitrary &lt;span style="font-style: italic"&gt;ApplicationRecord&lt;/span&gt; class?&lt;br /&gt;
&lt;br /&gt;
The primary reason why a developer puts code into &lt;span style="font-style: italic"&gt;ApplicationController&lt;/span&gt; is for &lt;span style="font-weight: bold;"&gt;code reuse&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;changing default behavior&lt;/span&gt;. The ultimate result is that this class becomes a dumping ground for any common methods required across two or more controllers. Ruby has a better pattern for reusing methods and changing behavior across classes: &lt;span style="font-weight: bold;"&gt;Modules&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
I create my own controller modules in the &lt;span style="font-style: italic"&gt;lib&lt;/span&gt; folder, and include them into &lt;span style="font-style: italic"&gt;ActionController::Base&lt;/span&gt;. If I want only certain controllers to be affected, the module defines a class level method, similar to the &lt;span style="font-style: italic"&gt;before_filter&lt;/span&gt; and &lt;span style="font-style: italic"&gt;has_many&lt;/span&gt; macros. For example, some controllers require a login. Rather than adding a filter to &lt;span style="font-style: italic"&gt;ApplicationController&lt;/span&gt;, I would make a 'require_login' module. My controllers could optionally use it like this:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717334.js?file=post_controller.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Why do I go through all this trouble? Because it (1) cuts one layer out of the inheritance tree, and (2) forces me to think about packaging functionality into small, testable modules. I encourage you to look at the code in your &lt;span style="font-style: italic"&gt;ApplicationController&lt;/span&gt;, and question whether any or all of your controllers should be inheriting from it.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-5130586814545070201?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/M81kRBot__E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/5130586814545070201/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=5130586814545070201" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/5130586814545070201?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/5130586814545070201?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/M81kRBot__E/i-killed-applicationcontroller.html" title="I killed ApplicationController" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2008/11/i-killed-applicationcontroller.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcDQnY-eip7ImA9WxRUE04.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-8729143752565526792</id><published>2008-11-21T21:25:00.000-08:00</published><updated>2008-11-21T21:34:33.852-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-21T21:34:33.852-08:00</app:edited><title>I am not dead</title><content type="html">&lt;div style="font-family:verdana"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;To the dedicated numbers subscribing to my blog: I'd like to notify everyone that I still exist. I just awakened from a temporary, semi-comatose state. Thankfully, I have numerous blog posts queued in my non-volatile persistence mechanism.&lt;br /&gt;&lt;br /&gt;Please stand by for tips in perfectionism with HTTP, SQL and Ruby on Rails.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-8729143752565526792?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/cji5w9vPb5U" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/8729143752565526792/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=8729143752565526792" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/8729143752565526792?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/8729143752565526792?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/cji5w9vPb5U/i-am-not-dead.html" title="I am not dead" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2008/11/i-am-not-dead.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU4MQHo8eCp7ImA9Wx9TGEw.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-4175402619744940285</id><published>2008-09-15T22:38:00.000-07:00</published><updated>2010-11-26T15:26:21.470-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-26T15:26:21.470-08:00</app:edited><title>Ruby 1.8.7's Enumerator Class</title><content type="html">&lt;div style="font-family:verdana"&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Early in my Ruby career, I found myself needing access to the &lt;span style="font-style: italic;"&gt;index&lt;/span&gt; while using &lt;span style="font-weight: bold;"&gt;Enumerable&lt;/span&gt; methods such as &lt;span style="font-style: italic;"&gt;map&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;select&lt;/span&gt;. I quickly discovered the obscurely documented &lt;span style="font-style: italic;"&gt;enum_for&lt;/span&gt; method:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717340.js?file=enum_for.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Since MacPorts is now on Ruby 1.8.7, I read the &lt;a href="http://svn.ruby-lang.org/repos/ruby/tags/v1_8_7_preview1/NEWS"&gt;1.8.7 summary log&lt;/a&gt; and noticed a bunch of existing methods that now "Return an enumerator if no block is given." I soon realized that the above can now be written as:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717340.js?file=each_with_index.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;It's a seemingly simple and minor improvement, but I think this change will encourage developers to use &lt;span style="font-weight: bold;"&gt;Enumerator&lt;/span&gt; more often with Ruby. For example, the &lt;span style="font-style: italic;"&gt;enum_for&lt;/span&gt; method is never used in Rails 2.1. Contrarily, I bet that the new "Return an enumerator if no block is given" change will be used in Rails (eventually).&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;Arbitrary Uses&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Since Integer#downto returns an Enumerator, let's write factorial:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717340.js?file=factorial.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Why not sort the letters in a word? Let's combine &lt;span style="font-style: italic;"&gt;each_char&lt;/span&gt; with &lt;span style="font-style: italic;"&gt;sort:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717340.js?file=each_char.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Since &lt;span style="font-weight: bold;"&gt;Enumerator&lt;/span&gt; is just an object, we can pass it around, and customize how other methods behave. For example, here I determine whether the items are processed in ascending or descending order:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717340.js?file=do_stuff.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;All of this fun can be added to prior versions of Ruby by opening classes. I think this might work...&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717340.js?file=extend.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Please comment and let me know if there are better uses for this change!&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-4175402619744940285?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/Cdmj2huPniQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/4175402619744940285/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=4175402619744940285" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/4175402619744940285?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/4175402619744940285?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/Cdmj2huPniQ/ruby-187s-enumerator-class.html" title="Ruby 1.8.7's Enumerator Class" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2008/09/ruby-187s-enumerator-class.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEMFRnw4fSp7ImA9WxRTEEs.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-1903235126181481333</id><published>2008-08-29T18:47:00.000-07:00</published><updated>2008-08-29T19:13:37.235-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-29T19:13:37.235-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="action_view" /><title>Obsessing over URLs</title><content type="html">&lt;div style="font-family:verdana"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;One of the most important components of a website is URL design. I have obsessed over URLs since the beginning of time, and &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;REST&lt;/a&gt; caused me to focus on them even more. Here's a classic example of a clean URL:&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;www.strictlyuntyped.com/articles/1/comments/1&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;This seems quite ordinary by today's standards. But admit it, a few years ago us web developers were getting really excited about this stuff.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;What was the original problem?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Let's start from the beginning. The 'dirty' version of the above URL:&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;www.strictlyuntyped.com/read?article_id=1&amp;comment_id=1&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;One of the most notable problems with this type of URL is that the user sees it. The URL is an important piece of the user experience, since (1) it is displayed at the top of the browser window, (2) users determine where they are on a site by the URL, and (3) they type in and share URLs, so they must be 'readable'. Essentially, no information is provided to the user about the structure and/or hierarchy of your site.&lt;br /&gt;&lt;br /&gt;The second problem with dirty URLs are developer facing. The application code pretty much consists of a function that takes in a hash. A Ruby analogy would be the following method:&lt;/span&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;&lt;br /&gt;  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;&lt;tt&gt;&lt;br /&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;&lt;br /&gt;  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;read&lt;/span&gt;(options={})&lt;/pre&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;The method has zero self-documentation, and a comment would be required to determine what options it expects. Our world here is essentially a one dimensional array of methods that take a hash.&lt;br /&gt;&lt;br /&gt;As a comparison, here is what I believe the Rails analogy of the aforementioned clean URL would be:&lt;/span&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;&lt;br /&gt;  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;&lt;tt&gt;&lt;br /&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;&lt;br /&gt;  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="co"&gt;Article&lt;/span&gt;.find(article_id).comments.find(comment_id)&lt;/pre&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;The idea of introducing structure into a line of characters is a simple, yet profound, concept. It seems to have become a requirement for any 'Web 2.0' site.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Don't go overboard with clean RESTful URLs&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Clean URLs and REST works incredibly well for content managing systems such as blogs. Without coincidence, Rails works very well with these types of systems. In other cases, I see myself, and others, forcing a square through a round hole when it comes to URL design. Here are two mistakes that myself, and probably others, have made. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Mistake #1: Overcomplicated Hierarchies&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;There exists an implicit hierarchy to clean URL design; an article having comments is a good example. On the other hand, there is no reason to create deeply nested hierarchies for the sake of representing the real world. &lt;a href="http://weblog.jamisbuck.org/2007/2/5/nesting-resources"&gt;the { buckblogs :here }&lt;/a&gt; says not to nest resources more than one level deep from a programmatic point of view. I completely agree, and amend his reasons from an information design perspective. If you were to make a website about animals, would the urls represent &lt;a href="http://upload.wikimedia.org/wikipedia/commons/5/5f/Biological_classification_L_Pengo.svg"&gt;biological classifications?&lt;/a&gt; Here is what the URL for a &lt;span style="font-style"&gt;lion&lt;/span&gt; will look like:&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;/kingdom/animalia/phylum/chordata/class/mammalia/order/carnivora/family/felidae/genus/panthera/species/lion&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;The point is, flatten your hierarchy and &lt;a href="http://blogs.sun.com/MartinHardee/entry/tufte_story_answerbook"&gt;make Tufte proud!&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Mistake #2: Unordered Parameters&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Oftentimes, the input required for a URL does not fit in a hierarchy. A great analogy is a Ruby method. Think of how many methods in Ruby on Rails use the following format:&lt;/span&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;&lt;br /&gt;  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;&lt;tt&gt;&lt;br /&gt;&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;&lt;br /&gt;  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;some_method&lt;/span&gt;(foo, bar, options = {})&lt;/pre&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;This method makes the options optional, and they can be passed in without any specific order. Why not leverage these same benefits with a URL? With that in mind, there is nothing wrong with the following URL:&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;www.strictlyuntyped.com/articles/1/comments?order=date&amp;rating=4&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;How else would Google Maps make &lt;a href="http://maps.google.com/maps?f=q&amp;hl=en&amp;geocode=&amp;q=Machu+Picchu,+peru&amp;ie=UTF8&amp;cd=1&amp;ll=-13.162849,-72.515821&amp;spn=5.678343,8.360596&amp;z=7"&gt;locations sharable?&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To wrap up my ramblings, don't get stuck with your project obsessing over how perfect your URLs are. Keep the hierarchy simple, and use a hash of parameters when you need it.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-1903235126181481333?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/qT99kADnFR4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/1903235126181481333/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=1903235126181481333" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/1903235126181481333?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/1903235126181481333?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/qT99kADnFR4/obsessing-over-urls.html" title="Obsessing over URLs" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2008/08/obsessing-over-urls.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUNQXg-cSp7ImA9Wx5aE08.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-6586568227825883988</id><published>2008-08-14T09:40:00.001-07:00</published><updated>2010-11-09T09:21:30.659-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-09T09:21:30.659-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="active_record" /><category scheme="http://www.blogger.com/atom/ns#" term="ruby on rails" /><category scheme="http://www.blogger.com/atom/ns#" term="fixtures" /><title>ActiveRecord: Can haz namespaces?</title><content type="html">&lt;div style="font-family:verdana"&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;There are plenty of blog postings from &lt;a href="http://blog.hasmanythrough.com/2008/5/6/a-simple-alternative-to-namespaced-models"&gt;has_many :through&lt;/a&gt;, &lt;a href="http://errtheblog.com/posts/3-organize-your-models"&gt;err the blog&lt;/a&gt; and &lt;a href="http://m.onkey.org/2007/12/9/namespaced-models"&gt;Pratik's blog&lt;/a&gt; describing how to completely avoid namespaced models. I unfortunately discovered these sites only after struggling with namespaces myself.&lt;br /&gt;
&lt;br /&gt;
If namespaces were completely unsupported by ActiveRecord, I would leave it at that. Contrarily, namespaces are moderately supported, but lead first timers to the spooky edges of the Rails framework.&lt;br /&gt;
&lt;br /&gt;
After giving it some thought, I determined that the best way to describe the state of namespacing in ActiveRecord is to act as a first time novice, pretending to use them for the first time!&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;The Requirements&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;I am an intern working for a company that has built their entire website with Ruby on Rails. My boss wants me to add statistics tracking similar to Google Analytics, and he wants it all to go into the &lt;span style="font-weight: bold;"&gt;Statistics::&lt;/span&gt; namespace. The initial requirements include tracking the milliseconds that each HTTP request took to complete, how long users remained logged into their session, and which session each request belonged to.&lt;br /&gt;
&lt;br /&gt;
This sounds like a really easy project, and I want to impress my boss by using all the best practices and conventions of Rails.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;Table Name Surprise&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;I will start with a model that stores the length of each request. It makes sense to use a Rails script to generate &lt;span style="font-weight: bold;"&gt;Statistics::Request&lt;/span&gt;:&lt;/span&gt;&lt;pre&gt;ruby script/generate model Statistics::Request milliseconds:integer
  create  app/models/statistics
  create  test/unit/statistics
  create  test/fixtures/statistics
  create  app/models/statistics/request.rb
  create  test/unit/statistics/request_test.rb
  create  test/fixtures/statistics_requests.yml
  create  db/migrate
  create  db/migrate/20080814034925_create_statistics_requests.rb&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;The generator conveniently created a statistics folder inside both &lt;span style="font-style: italic;"&gt;app/models&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;test/unit&lt;/span&gt;. I am a little bit confused as to why the folder &lt;span style="font-style: italic;"&gt;test/fixtures/statistics&lt;/span&gt; was created, when the actual fixture was placed in &lt;span style="font-style: italic;"&gt;test/fixtures/statistics_requests.yml&lt;/span&gt;, but I will figure that out later.&lt;br /&gt;
&lt;br /&gt;
The table name in the migration is &lt;span style="font-style: italic;"&gt;statistics_requests&lt;/span&gt;, so I immediately assume that table names include the namespace. After migrating the database, I fire up the console to try out the model:&lt;/span&gt;&lt;pre&gt;&amp;gt;&amp;gt; Statistics::Request.create(:milliseconds =&gt; 10)
ActiveRecord::StatementInvalid: Could not find table 'requests'&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;How strange, I thought the table's name is &lt;span&gt;statistics_requests&lt;/span&gt;. Just to make sure:&lt;/span&gt;&lt;pre&gt;&amp;gt;&amp;gt; Statistics::Request.table_name
=&gt; "requests"&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;Is this a bug in Rails? Apparently not. I guess it's time to do some dirty monkey patching:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/668764.js?file=monkey.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Good, now the model can find its table. Time to write some fixtures and tests.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;Tests are looking good&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Feeling confident after getting my namespaced model to work, it would be nice to make sure the the new test runs:&lt;/span&gt;&lt;br /&gt;
&lt;pre&gt;rake test:units
... "test/unit/statistics/request_test.rb"
1 tests, 1 assertions, 0 failures, 0 errors&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;Sweet - It looks like tests are discovered recursively in the test/unit folder.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;Associations&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;I need to add the &lt;span style="font-weight: bold;"&gt;Statistics::Session&lt;/span&gt; model, and also update &lt;span style="font-weight: bold;"&gt;Statistics::Request&lt;/span&gt; to belong to a session.&lt;br /&gt;
&lt;br /&gt;
The migration:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/668764.js?file=migration.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;The model:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/668764.js?file=request.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;I use the console to test out the association:&lt;/span&gt;&lt;br /&gt;
&lt;pre&gt;&gt;&gt; session = Statistics::Session.create(:start =&gt; 4.hours.ago, :end =&gt; Time.now)
=&gt; #&amp;lt;Statistics::Session id: 1, start: "2008-08-14 00:42:00", end: "2008-08-14 04:42:00"&amp;gt;
&gt;&gt; request = Statistics::Request.create(:milliseconds =&gt; 10, :session =&gt; session)
ArgumentError: Statistics is not missing constant Session!&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;This is a bizarre error. It turns out that Rails can't find &lt;span style="font-weight: bold;"&gt;Statistics::Request&lt;/span&gt; from &lt;span style="font-weight: bold;"&gt;Statistics::Session&lt;/span&gt;. I finally figured out that I need to do this:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/668764.js?file=belongs_to.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;It would make more sense if I only had to specify :class_name if it existed in a different namespace.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;Namespaced Fixtures = WTF?&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Development and testing will be easier if I generate some fixture data. Remember when the model generator script created an unused folder?&lt;/span&gt;&lt;br /&gt;
&lt;pre&gt;create  test/fixtures/statistics
...
create  test/fixtures/statistics_requests.yml&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;Based on the other conventions, it seems like this file belongs in test/fixtures/statistics/requests.yml. I'll move it there, and load up some fake data:&lt;/span&gt;&lt;br /&gt;
&lt;pre&gt;rake db:fixtures:load&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;It will be fun to play around with all that fixture data:&lt;/span&gt;&lt;br /&gt;
&lt;pre&gt;&amp;gt;&amp;gt; Statistics::Request.count
=&amp;gt; 0&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;How bizarre, the data did not even get loaded. I soon find out that unlike unit tests, fixture files are not recursively loaded. The file can't be moved after all.&lt;br /&gt;
&lt;br /&gt;
I need to get the request -&gt; session association working in the fixtures too. Let me edit &lt;span style="font-style: italic"&gt;statistics_sessions.yml&lt;/span&gt; and &lt;span style="font-style: italic"&gt;statistics_requests.yml&lt;/span&gt;&lt;/span&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/668764.js?file=fixtures.yml"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Unfortunately, this does not work:&lt;/span&gt;&lt;br /&gt;
&lt;pre&gt;rake db:fixtures:load
rake aborted!
SQLite3::SQLException: table statistics_requests has no column named session...&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;For some reason, the label referencing is not working with my namespaced models. I guess I need to hand hold Rails on this one:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/668764.js?file=fixture_update.yml"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;Observers - OMG they work!&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Feeling a little down after my battle with fixtures, I decide to make a request observer that logs whenever we get a request:&lt;/span&gt;&lt;br /&gt;
&lt;pre&gt;ruby script/generate observer Statistics::Request
  exists  app/models/statistics
  exists  test/unit/statistics
  create  app/models/statistics/request_observer.rb
  create  test/unit/statistics/request_observer_test.rb&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;Looking good so far. Let me implement the class:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/668764.js?file=request_observer.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;I also won't forget to add the following line to &lt;span style="font-style: italic;"&gt;environment.rb&lt;/span&gt;:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/668764.js?file=environment.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;And viola, it all works:&lt;/span&gt;&lt;br /&gt;
&lt;pre&gt;&amp;gt;&amp;gt; Statistics::Request.create(:milliseconds =&gt; 10)
We got a hit!!!&lt;/pre&gt;&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;In Summary&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Ok, I'm done playing stupid. My final word is that namespaced models can be made to work, but there are some rough edges. Some final tips for you:&lt;ul&gt;&lt;li&gt;Don't have conflicting namespaces and class names. For example, I should not introduce a class named &lt;span style="font-weight: bold;"&gt;Statistics&lt;/span&gt; in the above example. Otherwise, I will end up seeing the following message: "warning: toplevel constant Statistics referenced by Statistics::Statistics".&lt;/li&gt;
&lt;li&gt;Even when referencing other classes in the same namespace, it is best to always include the namespace prefix. Otherwise, you will run into issues with conflicting class names across different namespaces and Rails' automagical class loading.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;br /&gt;
Some things that Rails should do:&lt;ul&gt;&lt;li&gt;All APIs in Rails that support defining classes by Symbols should also support Strings. I was fortunate that I could pass in 'statistics/request_observer' to active_record.observers. However, other methods such as &lt;span style="font-weight: bold;"&gt;ActiveRecord::Observer.observe&lt;/span&gt; do not support strings.&lt;/li&gt;
&lt;li&gt;I believe that there is enough reason to support prefixing database table names with the namespace. This is as simple as introducing a new option to ActiveRecord called 'include_namespace_in_table_name'.&lt;/li&gt;
&lt;li&gt;Fix the fixtures.&lt;/li&gt;
&lt;/ul&gt;&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-6586568227825883988?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/cT_Taw3Jxa8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/6586568227825883988/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=6586568227825883988" title="12 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/6586568227825883988?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/6586568227825883988?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/cT_Taw3Jxa8/activerecord-can-haz-namespaces.html" title="ActiveRecord: Can haz namespaces?" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>12</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2008/08/activerecord-can-haz-namespaces.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUIGQ306eip7ImA9WxdbE04.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-3850579370592097544</id><published>2008-08-09T19:55:00.000-07:00</published><updated>2008-08-09T20:05:22.312-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-09T20:05:22.312-07:00</app:edited><title>Googtaculous, now with SSL support</title><content type="html">&lt;div style="font-family:verdana"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;This is just a short note. Google recently &lt;a href="http://googleajaxsearchapi.blogspot.com/2008/07/ajax-libraries-ssl-support-is-live.html"&gt;added SSL support&lt;/a&gt; to their AJAX Libraries API. &lt;a href="http://github.com/matthuhiggins/googtaculous/tree/master"&gt;Googtaculous&lt;/a&gt; will now automatically use &lt;span style="font-style: italic"&gt;https&lt;/span&gt; if the incoming request comes in over SSL. (http://github.com/matthuhiggins/googtaculous/tree/master).&lt;br /&gt;&lt;br /&gt;Browsers show warnings if a website includes both &lt;span style="font-style: italic"&gt;http&lt;/span&gt; and &lt;span style="font-style: italic"&gt;https&lt;/span&gt; requests. A few readers asked for this addition.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-3850579370592097544?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/pZY6gsQZ5UA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/3850579370592097544/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=3850579370592097544" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/3850579370592097544?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/3850579370592097544?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/pZY6gsQZ5UA/googtaculous-now-with-ssl-support.html" title="Googtaculous, now with SSL support" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2008/08/googtaculous-now-with-ssl-support.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0INRns5cCp7ImA9Wx9TGEw.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-6641486040252378282</id><published>2008-08-05T10:04:00.000-07:00</published><updated>2010-11-26T15:53:17.528-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-26T15:53:17.528-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="prototype" /><title>In place Array methods for Prototype</title><content type="html">&lt;div style="font-family:verdana"&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Unlike Ruby, Prototype does not offer in place iterators for Array methods such as &lt;span style="font-weight: bold;"&gt;compact&lt;/span&gt;, &lt;span style="font-weight: bold;"&gt;map&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;reject&lt;/span&gt;. I started down the road of implementing these methods, and discovered significant improvements with large arrays. Since Javascript does not support the "!" character in function names, I decided to name the in place versions with underscore prefixes.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;map&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;_map&lt;/span&gt; is simple to implement. We replace the value in each index with the result of the iterator function:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717359.js?file=map.js"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;In this case, and the remaining ones, &lt;span style="font-style: italic;"&gt;this&lt;/span&gt; is returned so that the methods can be chained.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;reject&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;For in place &lt;span style="font-weight: bold;"&gt;_reject&lt;/span&gt;, I scan the array once from left to right. Elements that are not rejected are placed in the array from left to right, and finally the length is truncated. I believe it is important to maintain the original order of the elements:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717359.js?file=reject.js"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;compact&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;&lt;span style="font-weight: bold;"&gt;_compact&lt;/span&gt; is very similar to &lt;span style="font-weight: bold;"&gt;reject&lt;/span&gt;&lt;/span&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717359.js?file=compact.js"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;The above implementation can be shortened by using _reject, but it significantly reduces performance. For completeness, that might be written as:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717359.js?file=reject2.js"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;Results&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;These are results in Firefox 3, using an array of 100,000 numbers and null values. Changing the size did not seem to affect the relative performance.&lt;br /&gt;
&lt;/span&gt;&lt;table&gt;&lt;tr&gt;&lt;th&gt;Method&lt;/th&gt;&lt;th&gt;Prototype Time&lt;/th&gt;&lt;th&gt;In Place Time&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;map&lt;/td&gt;&lt;td&gt;159ms&lt;/td&gt;&lt;td&gt;42ms&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;reject&lt;/td&gt;&lt;td&gt;158ms&lt;/td&gt;&lt;td&gt;45ms&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;compact&lt;/td&gt;&lt;td&gt;161ms&lt;/td&gt;&lt;td&gt;13ms&lt;/td&gt;&lt;/tr&gt;

&lt;/table&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;One should probably do a more comprehensive test, but these results are enough to show that performance gains can be made with my faster versions. In addition, less memory is being used.&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-6641486040252378282?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/OBKxXQX6tmc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/6641486040252378282/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=6641486040252378282" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/6641486040252378282?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/6641486040252378282?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/OBKxXQX6tmc/in-place-array-methods-for-prototype.html" title="In place Array methods for Prototype" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2008/08/in-place-array-methods-for-prototype.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUGR3wyeSp7ImA9Wx9TGEw.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-2759932306689635505</id><published>2008-07-22T09:35:00.000-07:00</published><updated>2010-11-26T16:03:46.291-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-26T16:03:46.291-08:00</app:edited><title>MySql Lovin' Part 3: Summing up with group_concat</title><content type="html">&lt;div style="font-family:verdana"&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Ruby on Rails provides some handy methods for using SQL aggregate functions:&lt;ul&gt;&lt;li&gt;count&lt;/li&gt;
&lt;li&gt;average&lt;/li&gt;
&lt;li&gt;minimum&lt;/li&gt;
&lt;li&gt;maximum&lt;/li&gt;
&lt;li&gt;sum&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
While this is a good start, MySql has &lt;a href="http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html"&gt;additional functions&lt;/a&gt; that are not included in this list. I will show an example using &lt;span style="font-style: italic;"&gt;group_concat&lt;/span&gt;&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;group_concat&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;If you recall from &lt;a href="http://www.strictlyuntyped.com/2008/07/mysql-lovin-part-1-on-duplicate-key.html"&gt;my post about on duplicate key update&lt;/a&gt;, we had a &lt;span style="font-weight: bold;"&gt;Post&lt;/span&gt; model that included a virtual attribute called &lt;span style="font-style: italic;"&gt;tag_list:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717369.js?file=slow.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;This code retrieves all tags for the post, creates Tag objects, maps that to an array of strings, and joins them together. While this code looks nifty, it is performing a hefty amount of work for the task.&lt;br /&gt;
&lt;br /&gt;
Thankfully, MySql has a &lt;span style="font-style: italic;"&gt;group_concat&lt;/span&gt; function, and Rails exposes a &lt;span style="font-style: italic;"&gt;calculate&lt;/span&gt; method to perform arbitrary aggregate functions by name. Without further ado, here is how we can use group_concat:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717369.js?file=faster.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;The separator defaults to ','. If you want to change it, sneak in a separator command:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717369.js?file=separator.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;group_concat will be significantly faster than the original method.&lt;br /&gt;
&lt;br /&gt;
Another group of underused aggregate functions are &lt;span style="font-style: italic;"&gt;bit_and&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;bit_or&lt;/span&gt;, and &lt;span style="font-style: italic;"&gt;bit_xor&lt;/span&gt;. If you have a many-many association between a model and an enumerated set of 64 or less items, this information can be stored in a single BIGINT field on the model.&lt;br /&gt;
&lt;br /&gt;
This wraps up my unglamorous MySql series. If I saved one clock cycle on one database server, then I claim success.&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-2759932306689635505?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/XH-Yvg1DeoU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/2759932306689635505/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=2759932306689635505" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/2759932306689635505?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/2759932306689635505?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/XH-Yvg1DeoU/mysql-lovin-part-3-summing-up-with.html" title="MySql Lovin' Part 3: Summing up with group_concat" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2008/07/mysql-lovin-part-3-summing-up-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEIASXc8eCp7ImA9Wx9TGEw.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-4557482446352591842</id><published>2008-07-12T11:17:00.000-07:00</published><updated>2010-11-26T16:09:08.970-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-26T16:09:08.970-08:00</app:edited><title>MySql Lovin' Part 2: Add New Data Types To Migrations</title><content type="html">&lt;div style="font-family:verdana"&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;This is a follow up to last week's &lt;a href="http://www.strictlyuntyped.com/2008/07/mysql-lovin-part-1-on-duplicate-key.html"&gt;MySql Lovin Part 1&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
You will eventually want to use MySql specific data types. While arbitrary SQL statements can be executed in migrations, an alternative is to extend the MySql adapter to support new types of columns.&lt;br /&gt;
&lt;br /&gt;
Two examples of columns I use are:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;BIGINT. Rails 2.1 attempts to use the :limit option to predict you want a BIGINT, but there seems to be confusion in Rails source about what the &lt;span style="font-weight: bold;"&gt;N&lt;/span&gt; means when you write BIGINT(N). Nevertheless, BIGINT always has the same maximum and minimum limit, and if I want to use one, I like to be explicit.&lt;/li&gt;

&lt;li&gt;Primary Key without auto increment. Sometimes I have enums defined in Ruby code, and want to explicitly define their value when inserting into the database, rather than having their id value automatically incremented by the database.&lt;/li&gt;

&lt;/ul&gt;&lt;br /&gt;
Let's add support for these columns, so that they can be used with &lt;span style="font-style: italic"&gt;create_table&lt;/span&gt;. First, have a look at &lt;a href="http://github.com/rails/rails/tree/v2.1.0/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb#L194"&gt;native_database_types&lt;/a&gt;, defined in &lt;span style="font-weight: bold"&gt;ActiveRecord::ConnectionAdapters::MysqlAdapter.&lt;/span&gt; Rails provides no facility to register more column types with an adapter, but that does not prevent merging them into the column type hash:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717379.js?file=new_natives.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;With the new types added, they can be used in migrations:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717379.js?file=create_table_1.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;Shorthand Columns&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;To make these migrations a bit more appealing, extend &lt;span style="font-weight: bold"&gt;ActiveRecord::ConnectionAdapters::TableDefinition&lt;/span&gt; to support shorthanded column names:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717379.js?file=table_definition.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Refactor the migration:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717379.js?file=refactor.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;Adding Native Support to Rails&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;It would be nifty if Rails allowed you to perform the above in an initializer (very similar to how you register mime_types). For example:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717379.js?file=rails.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;I might follow this up with a Rails patch, but need to think about it more. Also, the weather is too nice for me to continue blogging.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-4557482446352591842?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/Rn6ws1MoH4g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/4557482446352591842/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=4557482446352591842" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/4557482446352591842?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/4557482446352591842?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/Rn6ws1MoH4g/mysql-lovin-part-2-adding-new-column.html" title="MySql Lovin' Part 2: Add New Data Types To Migrations" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2008/07/mysql-lovin-part-2-adding-new-column.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEcGQ3s9eSp7ImA9Wx9TGEw.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-4388166664159702908</id><published>2008-07-04T15:06:00.000-07:00</published><updated>2010-11-26T16:00:22.561-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-26T16:00:22.561-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mysql" /><category scheme="http://www.blogger.com/atom/ns#" term="ruby on rails" /><title>MySql Lovin' Part 1: On Duplicate Key Update</title><content type="html">&lt;div style="font-family:verdana"&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;By coding through the ActiveRecord abstraction, we lose close ties to SQL. This is a major selling point for Rails, but it should not be why you are sold on Rails. &lt;br /&gt;
&lt;br /&gt;
Avoiding vendor specific database features is silly, and doing so does not make you a better Rails developer. Database neutrality has never helped me because I have yet to swap database vendors. If I did need to swap, it would be due to a vendor specific feature. ActiveRecord is great for the majority of operations, but you should not live exclusively within its constraints. And so I begin the &lt;span style="font-style: italic; font-weight: bold;"&gt;MySql Lovin'&lt;/span&gt; series...&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;Perfect Rails Code&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Start with a simple data model for a blog. A post has &lt;span style="font-style: italic;"&gt;text&lt;/span&gt;, and can have zero or more &lt;span style="font-style: italic;"&gt;tags&lt;/span&gt;. Here is what the migration looks like:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717365.js?file=migration.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;The &lt;span style="font-weight: bold"&gt;tags&lt;/span&gt; table also keeps track of the total posts per tag.&lt;br /&gt;
&lt;br /&gt;
The models for the blog might look like this:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717365.js?file=models_orig.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Notice that the &lt;span style="font-weight: bold"&gt;Post&lt;/span&gt; model has a virtual &lt;span style="font-style: italic;"&gt;tag_list&lt;/span&gt; attribute. This automatically splits a comma delimited list of tags, creates new tags if necessary, and generates the associations between posts and tags.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;Too Many Queries&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Fill out the form:&lt;br /&gt;
&lt;br /&gt;
&lt;img style="margin:0 10px 10px 0" src="http://matthewhiggins.com/blog/post_form.png" border="0" alt="Form" /&gt;&lt;br /&gt;
&lt;br /&gt;
Now check the query log to see what queries hit the database:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717365.js?file=slow.sql"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;16 queries. Gross, let's try to do better.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;On Duplicate Key Update&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;MySql's &lt;a href="http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html"&gt;INSERT ... ON DUPLICATE KEY UPDATE&lt;/a&gt; is a perfect solution to reduce the number of queries. It can be used to:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Insert non-existing tags&lt;/li&gt;
&lt;li&gt;Update the counter cache for posts per tag.&lt;/li&gt;
&lt;li&gt;Remove the need to instantiate a &lt;span style="font-weight: bold;"&gt;Tag&lt;/span&gt; object for each tag.&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Let's give it a try:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717365.js?file=models_new.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;That SQL code sure looks ugly. It probably belongs in the &lt;span style="font-weight: bold"&gt;Tag&lt;/span&gt; class, and can be generated automatically from the model's attributes. What if I made a plugin that added &lt;span style="font-style: italic"&gt;create_or_update&lt;/span&gt; to ActiveRecord::Base?&lt;br /&gt;
&lt;br /&gt;
More importantly, the number of queries have decreased:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/717365.js?file=faster.sql"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;This is a good start. The number of queries has decreased by a 2x factor, and Tag objects are no longer being created.&lt;br /&gt;
&lt;br /&gt;
By alas, what is that query on &lt;span style="font-style: italic"&gt;line 4&lt;/span&gt; for? It looks like Rails runs this query after assigning to &lt;span style="font-style: italic"&gt;tag_ids&lt;/span&gt;. This can be avoided by directly creating the entries for &lt;span style="font-style: italic"&gt;post_tags&lt;/span&gt;, but I can accept this annoyance for today.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-4388166664159702908?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/DkUci-rJpWE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/4388166664159702908/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=4388166664159702908" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/4388166664159702908?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/4388166664159702908?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/DkUci-rJpWE/mysql-lovin-part-1-on-duplicate-key.html" title="MySql Lovin' Part 1: On Duplicate Key Update" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>4</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2008/07/mysql-lovin-part-1-on-duplicate-key.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cDR3o6eip7ImA9WxdXFUg.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-4565300314384793705</id><published>2008-06-27T02:17:00.001-07:00</published><updated>2008-06-27T02:31:16.412-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-06-27T02:31:16.412-07:00</app:edited><title>Broken 'pre' tags with Blogger</title><content type="html">&lt;span style="font-family: verdana;font-size:85%;" &gt;&lt;br /&gt;Sometime in the last week, a significant change was introduced into Blogger. Previously, any content inside of a &amp;lt;pre&gt; section was left alone. Now, a &amp;lt;br/&amp;gt; tag is insterted for every line break within a &amp;lt;pre&gt; tag, which results in a double line break. As a result, all of my code snippets have an extra line break.&lt;br /&gt;&lt;br /&gt;I will write a more relevant post tomorrow. I just wanted to explain why my existing snippets look wrong.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-4565300314384793705?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/dxt7QZ5deTA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/4565300314384793705/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=4565300314384793705" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/4565300314384793705?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/4565300314384793705?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/dxt7QZ5deTA/broken-pre-tags-with-blogger.html" title="Broken 'pre' tags with Blogger" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>4</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2008/06/broken-pre-tags-with-blogger.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMGRHk8eCp7ImA9Wx5aEkU.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-4913035150240439953</id><published>2008-06-24T08:57:00.000-07:00</published><updated>2010-11-08T21:27:05.770-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-08T21:27:05.770-08:00</app:edited><title>Googtaculous</title><content type="html">&lt;div style="font-family:verdana;"&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;&lt;br /&gt;
To follow up on my &lt;a href="http://www.strictlyuntyped.com/2008/06/using-google-ajax-libraries-api-with.html"&gt;post about Google's Ajax library API&lt;/a&gt;, I made a plugin that you can install to make your life easier.&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;pre&gt;script/plugin install git://github.com/matthuhiggins/googtaculous.git&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;
The name is pretty clever, eh?&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-4913035150240439953?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/6EKhY7EtEzM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/4913035150240439953/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=4913035150240439953" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/4913035150240439953?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/4913035150240439953?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/6EKhY7EtEzM/googtaculous.html" title="Googtaculous" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2008/06/googtaculous.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkQASH8zeSp7ImA9Wx5aEkU.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-6601085231558454132</id><published>2008-06-20T14:16:00.000-07:00</published><updated>2010-11-08T21:25:49.181-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-08T21:25:49.181-08:00</app:edited><title>Clearing memcache without restart</title><content type="html">&lt;div style="font-family:verdana;"&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;&lt;br /&gt;
Up until now, I always restarted memcache to clear it. However, you can make a rake task to do so:&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;script src="https://gist.github.com/668744.js?file=cache.rake"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;&lt;br /&gt;
Drop this into &lt;span style="font-style: italic;"&gt;/lib/tasks/cache.rake&lt;/span&gt;. Now just run the task:&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;pre&gt;rake cache:clear&lt;/pre&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;
This only works if you have configured &lt;span style="font-style: italic;"&gt;action_controller.cache_store&lt;/span&gt; to be memcache.&lt;br /&gt;
&lt;br /&gt;
Have a good weekend!&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-6601085231558454132?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/H_-uZyZgv2U" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/6601085231558454132/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=6601085231558454132" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/6601085231558454132?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/6601085231558454132?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/H_-uZyZgv2U/clearing-memcache-without-restart.html" title="Clearing memcache without restart" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2008/06/clearing-memcache-without-restart.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04AR386eCp7ImA9Wx5aEko.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-7957512591579180799</id><published>2008-06-14T09:05:00.000-07:00</published><updated>2010-11-08T21:19:06.110-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-08T21:19:06.110-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ruby on rails" /><title>Rails: Where to put the 'other' files</title><content type="html">&lt;div style="font-family:verdana;"&gt;&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;Introduction&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;When starting a Rails project, four golden folders are predefined: Models, Views, Controllers, Helpers. Could we possibly need anything more? In my experience, the answer is yes. This leads to the question of, where do these extra files go? Compared to models, views, controllers and helpers, Rails provides little guidance about where to put this other stuff. Fortunately, Rails comes packaged with two folders to put additional Ruby code: &lt;span style="font-weight: bold;"&gt;lib&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt; config/initializers&lt;/span&gt;. Each have their unique properties, and they can be used together to neatly package your Ruby code.&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;The weakling lib folder&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;In &lt;a href="http://pragprog.com/titles/rails3/agile-web-development-with-rails-third-edition"&gt;Agile Web Development on Rails&lt;/a&gt;, the authors describe how to use a naming convention, such that your &lt;span style="font-weight: bold;"&gt;lib &lt;/span&gt;file names match the classes they contain. For example, a class of FooBar must be in the file foo_bar.rb. Classes can even be namespaced. For example, Foo::Bar will be loaded if placed inside of foo/bar.rb.&lt;br /&gt;
&lt;br /&gt;
Files in &lt;span style="font-weight: bold;"&gt;lib&lt;/span&gt; are not loaded when Rails starts. Rails has overridden both Class.const_missing and Module.const_missing to dynamically load  the file based on the class name. In fact, this is exactly how Rails loads your models and controllers.&lt;br /&gt;
&lt;br /&gt;
While the functionality of the lib folder is nice, it is extremely limited. It prevents writing modules to extend or override the functionality of another class, because they will never get loaded.&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;The bloated initializers folder&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;Rails first loads the framework, then plugins, and finally, it loads the files inside of &lt;span style="font-weight: bold"&gt;config/initializers&lt;/span&gt; (in alphabetic order, no less). Previous to 2.0, naughty developers pasted code at the bottom of environment.rb, and the initializer folder was a welcome convention to help organize this madness.&lt;br /&gt;
&lt;br /&gt;
I find myself using the initializer folder to configure plugins such as HAML, or loading the action_mailer configuration out of a YML file.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, I see many code snippets showing how to extend the functionality of Rails simply by creating a new file in initializers, and pasting in the code. In a matter of fact, &lt;a href="http://www.strictlyuntyped.com/2008/06/using-google-ajax-libraries-api-with.html"&gt;my last post&lt;/a&gt; suggested doing this. This is OK in light doses, but after a few months of this practice, you will find yourself with an initializers folder with many files and little structure, not to mention that they get loaded in alphabetic order.&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;Lib folder, meet initializers&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;I think I hurt &lt;span style="font-weight: bold;"&gt;lib&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;initializer&lt;/span&gt;'s feelings. I feel bad about this, so maybe it is time to introduce them to each other. A simple example is in order:&lt;br /&gt;
&lt;br /&gt;
We want to add a new 'user_logger' mixin to ActionController::Base. Any controller can choose to enable 'user_logger', and it will put the current user's name in the log file for each request they make. This won't be the last time we extend ActionController's functionality in this project, so let's do it the Right Way.&lt;br /&gt;
&lt;br /&gt;
We first write the module. Start by creating a new folder inside of &lt;span style="font-weight: bold;"&gt;/lib&lt;/span&gt; called &lt;span style="font-weight: bold;"&gt;rails_extensions&lt;/span&gt;. Now paste this code inside the file &lt;span style="font-style: italic;"&gt;user_logger.rb:&lt;/span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/668734.js?file=module.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;&lt;br /&gt;
Next, create the file &lt;span style="font-style: italic;"&gt;rails_extensions.rb&lt;/span&gt; in &lt;span style="font-weight: bold;"&gt;/config/initializers.&lt;/span&gt; Paste this code inside:&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/668734.js?file=require.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;&lt;br /&gt;
You may want to create an even deeper directory structure inside of &lt;span style="font-weight: bold;"&gt;rails_extensions&lt;/span&gt;. In my larger projects, I keep a folder for action_controller, active_record, etc. Nonetheless, using &lt;span style="font-weight: bold;"&gt;initializers &lt;/span&gt;and &lt;span style="font-weight: bold;"&gt;lib&lt;/span&gt; together can help you avoid a bloated &lt;span style="font-weight: bold;"&gt;initializer&lt;/span&gt; folder and weak set of functionality in the &lt;span style="font-weight: bold;"&gt;lib &lt;/span&gt;folder.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-7957512591579180799?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/y2aEkeDvjGI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/7957512591579180799/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=7957512591579180799" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/7957512591579180799?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/7957512591579180799?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/y2aEkeDvjGI/rails-where-to-put-other-files.html" title="Rails: Where to put the 'other' files" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>7</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2008/06/rails-where-to-put-other-files.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04MQ30ycCp7ImA9Wx5aEko.&quot;"><id>tag:blogger.com,1999:blog-1845039873784052989.post-839464279903314302</id><published>2008-06-10T16:33:00.000-07:00</published><updated>2010-11-08T21:19:42.398-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-08T21:19:42.398-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="action_view" /><category scheme="http://www.blogger.com/atom/ns#" term="ruby on rails" /><title>Using Google Ajax Libraries API with Ruby on Rails</title><content type="html">&lt;span style="font-family:verdana;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;
Intro&lt;/span&gt;&lt;br /&gt;
The new &lt;a href="http://code.google.com/apis/ajaxlibs/"&gt;Google Ajax Libraries API&lt;/a&gt; can help you offload bandwidth from your site. Their servers are configured with gzip, expires headers and e-tags, which leads to good scores from &lt;a href="http://developer.yahoo.com/yslow/"&gt;YSlow&lt;/a&gt;. I will show two ways to use Google's new API to offload Ruby on Rails javascript (prototype and scriptaculous). In both solutions, your existing calls to &lt;span style="font-style: italic;"&gt;javascript_include_tag&lt;/span&gt; can be left the same, because all of the magic is handled beneath the covers.&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:verdana;"&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family:verdana;"&gt;&lt;br /&gt;
&lt;span style="font-size:100%;"&gt;&lt;span style="font-size:130%;"&gt;Implementation #1: Create a module&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;This first example is a module that chains the &lt;span style="font-style: italic;"&gt;expand_javascript_sources&lt;/span&gt;&lt;span style="font-style: italic;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=";font-family:verdana;font-size:85%;"  &gt; method found in &lt;/span&gt;&lt;span style="font-family:verdana;"&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;ActionView::Helpers::AssetTagHelper&lt;/span&gt;. If prototype or a scriptaculous file is loaded via javascript_include_tag, we will replace the normal functionality with a path to the file on Google's servers. Start by creating the file /config/initializers/&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:verdana;"&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-size:85%;"&gt;google_asset_tag_helper.rb&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:verdana;"&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-size:85%;"&gt;. Paste in the following:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/668732.js?file=module.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;This defines GoogleAssetTagHelper, which chains &lt;span style="font-style: italic;"&gt;expand_javascript_sources&lt;/span&gt;. The module is included into ActionView::Base. Notice that on line &lt;span style="font-weight: bold;"&gt;12&lt;/span&gt;, the original method is only aliased if &lt;span style="font-style: italic;"&gt;ActionController::Base.consider_all_requests_local&lt;/span&gt; is false. Since this is set to true in development mode, it is a sufficient way to determine whether or not Google AJAX Library should be used. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:verdana;"&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-size:85%;"&gt;If using the remote libraries in development is desirable, &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:verdana;"&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-size:85%;"&gt;the condition can be safely removed.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family:verdana;"&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size:130%;"&gt;Implementation #2: Assign lambda to ActionController::Base.asset_host&lt;/span&gt;&lt;br /&gt;
&lt;/span&gt;&lt;span style="font-size:85%;"&gt;An alternative solution uses ActionController::Base.asset_host to determine the root path to the javascript files. In /config/environments/production.rb, you find:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;config.action_controller.asset_host = "http://some.asset.host/"&lt;/pre&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;As of Rails 2.0.2, asset_host can a string or Proc. Since we want to conditionally change the asset_host based on what file is being include, a Proc is needed:&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/668732.js?file=asset_host.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;span style="font-family:verdana;"&gt;&lt;span style="font-size:85%;"&gt;In this example, the code assumes that you do not already have an asset_host defined. If you do, simply replace the false expression on line &lt;span style="font-weight: bold;"&gt;10&lt;/span&gt; with your original asset_host string.&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:verdana;"&gt;&lt;span style="font-size:85%;"&gt;(The variable &lt;span style="font-style: italic;"&gt;google_paths &lt;/span&gt;is defined inside of production.rb for brevity. &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:verdana;"&gt;&lt;span style="font-size:85%;"&gt;However, I recommend defining it as a constant elsewhere in your own project.&lt;/span&gt;&lt;/span&gt;)&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family:verdana;"&gt;&lt;span style="font-size:130%;"&gt;Using the javascript_include_tag&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size:85%;"&gt;As mentioned in the introduction, your existing &lt;span style="font-style: italic;"&gt;javascript_include_tag&lt;/span&gt; calls remain the same:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;javascript_include_tag 'prototype', 'effects', 'controls', 'application'&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1845039873784052989-839464279903314302?l=www.strictlyuntyped.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/strictlyuntyped/WqEA/~4/c_UqY_fkKsg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.strictlyuntyped.com/feeds/839464279903314302/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1845039873784052989&amp;postID=839464279903314302" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/839464279903314302?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1845039873784052989/posts/default/839464279903314302?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/strictlyuntyped/WqEA/~3/c_UqY_fkKsg/using-google-ajax-libraries-api-with.html" title="Using Google Ajax Libraries API with Ruby on Rails" /><author><name>Matthew Higgins</name><uri>http://www.blogger.com/profile/11424656227454708097</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>9</thr:total><feedburner:origLink>http://www.strictlyuntyped.com/2008/06/using-google-ajax-libraries-api-with.html</feedburner:origLink></entry></feed>

