<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Rails on PostgreSQL : </title>
    <link>http://railsonpostgresql.com/articles.rss</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>&lt;h3&gt;If you like Ruby on Rails, you'll love Rails on PostgreSQL!&lt;/h3&gt;</description>
    <item>
      <title>Converting Rails apps from MySQL to PostgreSQL</title>
      <description>&lt;p&gt;My roving Google bots turn up various notes on folks moving from MySQL to PostgreSQL.  Here are a few accumulated entries:&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;&lt;a href="http://blog.yangtheman.com/2010/01/30/how-to-convert-from-mysql-to-postgres/"&gt;Yangthaman describes&lt;/a&gt; the process of converting his app's database from MySQL to PostgreSQL.  He notes that 'Postgres does not allow option for &#8220;text&#8221; data type' - in Rails 3 with the latest &lt;code&gt;pg&lt;/code&gt; gem this works fine, though.  He cites &lt;a href="http://heroku.com/"&gt;Heroku&lt;/a&gt;'s PostgreSQL requirement as a motivator - this line of reasoning turned up a couple of times.
&lt;/li&gt;

&lt;br/&gt;&lt;li&gt;A detailed post from &lt;a href="http://vermicel.li/blog/2010/02/04/converting-a-rails-database-from-mysql-to-postgresql.html"&gt;Mike Castleman&lt;/a&gt; recommends ensuring that &lt;code&gt;config.active_record.schema_format&lt;/code&gt; is set to &lt;code&gt;:ruby&lt;/code&gt; and has a pointer to &lt;a href="http://sqlfairy.sourceforge.net/"&gt;SQL Fairy&lt;/a&gt; as a solution for complex schemas.  He notes differences in quoting styles (PostgreSQL uses double quotes) and reminds the reader of ActiveRecord's &lt;code&gt;quote_column_name&lt;/code&gt;, e.g.,  &lt;code&gt;Book.connection.quote_column_name('when') #=&gt; "\"when\""&lt;/code&gt;.   He notes that PostgreSQL has a native &lt;code&gt;boolean&lt;/code&gt; type, so if code was dependent on MySQL's &lt;code&gt;tinyint&lt;/code&gt; columns it will need to be cleaned up.  He mentions a few other changes they needed to make; definitely worth a read.  Finally, they open sourced their &lt;a href="http://github.com/mlc/rails_db_convert_using_adapters/blob/master/convert.rake"&gt;data conversion rake task&lt;/a&gt;; good stuff!&lt;/li&gt;

&lt;br/&gt;&lt;li&gt;&lt;a href="http://mindlev.wordpress.com/2010/03/15/migrating-mysql-to-postgresql-in-rails/"&gt;minlev&lt;/a&gt; converted his database using Michael Siebert's &lt;a href="http://github.com/siebertm/ar-dbcopy"&gt;AR-DBCopy&lt;/a&gt;.  This utility creates ActiveRecord classes on the fly to copy records from one AR connection to another.  Mindlev noted that this took 5 minutes for 100K records, so it's not something for anything other than smallish databases... but, it has its place.&lt;/li&gt;

&lt;br/&gt;&lt;li&gt;&lt;A href="http://mikewilliamson.wordpress.com/2010/04/19/postgres-and-rails-for-mysql-people/"&gt;Mike Williamson&lt;/a&gt; explores some PostgreSQL interactions using the various command line tools - &lt;code&gt;dropdb&lt;/code&gt;, &lt;code&gt;psql&lt;/code&gt;, &lt;code&gt;pg_dump&lt;/code&gt;, and so forth.  He also notes the PostgreSQL native &lt;code&gt;boolean&lt;/code&gt; type vs MySQL's &lt;code&gt;tinyint&lt;/code&gt;.&lt;/li&gt;

&lt;br/&gt;&lt;li&gt;&lt;a href="http://stackoverflow.com/questions/772111/switching-from-mysql-to-postgresql-tips-tricks-and-gotchas"&gt;StackOverflow&lt;/a&gt; has a long article with lots of resources on moving from MySQL to PostgreSQL.  It includes a pointer to the &lt;a href="http://wiki.postgresql.org/wiki/Converting_from_other_Databases_to_PostgreSQL#MySQL"&gt;PostgreSQL wiki page&lt;/a&gt; on switching from MySQL, which contains a variety of links to articles on the topic.  There's also a less detailed article on more or less the same thing on StackOverflow &lt;a href="http://stackoverflow.com/questions/724867/how-different-is-postgresql-to-mysql"&gt;here&lt;/a&gt;.&lt;/li&gt;

&lt;br/&gt;&lt;li&gt;&lt;a href="http://nopugs.com/2009/01/04/how-to-migrate-typo-from-mysql-to-postgresql"&gt;miles&lt;/a&gt; wrote up his notes on converting a MySQL &lt;a href="http://github.com/fdv/typo/wiki"&gt;typo&lt;/a&gt; blog instance to PostgreSQL.  The main hitch is the &lt;code&gt;tinyint&lt;/code&gt; to &lt;code&gt;boolean&lt;/code&gt; conversion, but he has the complete details of how he handled that.&lt;/li&gt;

&lt;br/&gt;&lt;li&gt;&lt;a href="http://adam.heroku.com/past/2009/2/11/taps_for_easy_database_transfers/"&gt;Adam Wiggins&lt;/a&gt; (of Heroku fame) describes using &lt;a href="http://github.com/ricardochimal/taps"&gt;taps&lt;/a&gt; to transfer data from a MySQL database to a PostgreSQL database.  This tool results in about the same transfer speeds as AR-DBCopy, so it's not suitable for hefty databases... but, still.  The taps git repo has had a bit of &lt;a href="http://github.com/ricardochimal/taps/commits/master"&gt;activity&lt;/a&gt; lately, so looks like that project is still going.&lt;/li&gt;

&lt;br/&gt;&lt;li&gt;&lt;a href="http://awesomeful.net/posts/45-postgresql-rails-and-why-you-should-care"&gt;Harold Gim&#233;nez&lt;/a&gt; wrote up a general overview of PostgreSQL's goodness, noting a variety of features like table partitioning, partial indexes, MVCC, tsearch2, PostGIS, and so on.  He notes that replication is getting better soon... and since PostgreSQL 9.0 is out, soon is now here.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;In summary, thanks to &lt;a href="http://heroku.com/"&gt;Heroku&lt;/a&gt; for providing a nudge for folks to switch to PostgreSQL!&lt;/p&gt;


</description>
      <pubDate>Wed, 20 Oct 2010 20:06:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:1deef71b-94f2-491e-8b8f-66228be1c22b</guid>
      <comments>http://railsonpostgresql.com/2010/10/20/converting-rails-apps-from-mysql-to-postgresql#comments</comments>
      <link>http://railsonpostgresql.com/2010/10/20/converting-rails-apps-from-mysql-to-postgresql</link>
    </item>
    <item>
      <title>Reducing log output from the Rails PostgreSQL connection adapter</title>
      <description>&lt;p&gt;When you write a Rails app that uses PostgreSQL you'll probably see your development log filled with log entries like this:&lt;/p&gt;

&lt;pre&gt;
 SQL (0.5ms)   SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull
 FROM pg_attribute a LEFT JOIN pg_attrdef d
 ON a.attrelid = d.adrelid AND a.attnum = d.adnum
 WHERE a.attrelid = '"reading_lists"'::regclass
 AND a.attnum &gt; 0 AND NOT a.attisdropped
 ORDER BY a.attnum
&lt;/pre&gt;

&lt;p&gt;This is all boilerplate stuff and definitely not part of your app.  So, how to get rid of it?   Just use Evgeniy Dolzhenko's &lt;a href="http://github.com/dolzenko/silent-postgres"&gt;silent-postgres&lt;/a&gt; gem.  Put this in your Rails 3 &lt;code&gt;Gemfile&lt;/code&gt; (or add a &lt;code&gt;config.gem&lt;/code&gt; entry in your &lt;code&gt;environment.rb&lt;/code&gt; file for Rails 2):&lt;/p&gt;

&lt;pre&gt;
group :development, :test do 
  gem 'silent-postgres'
end
&lt;/pre&gt;

&lt;p&gt;And that's it.  Cleaner logs, huzzah!&lt;/p&gt;

&lt;p&gt;The gem itself is only about 60 lines of code.  It creates an initializer that includes itself into &lt;code&gt;ActiveRecord::ConnectionAdapters::PostgreSQLAdapter&lt;/code&gt; and uses &lt;code&gt;alias_method_chain&lt;/code&gt; to silence output from a couple of methods - &lt;code&gt;tables&lt;/code&gt;, &lt;code&gt;pk_and_sequence_for&lt;/code&gt;, and a few others.  Good stuff!&lt;/p&gt;  





</description>
      <pubDate>Wed, 06 Oct 2010 20:36:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:a06bb62f-14f3-4785-8879-fd9def1f131d</guid>
      <comments>http://railsonpostgresql.com/2010/10/06/reducing-log-output-from-the-rails-postgresql-connection-adapter#comments</comments>
      <link>http://railsonpostgresql.com/2010/10/06/reducing-log-output-from-the-rails-postgresql-connection-adapter</link>
    </item>
    <item>
      <title>Rails 3, bundler, and the pg gem</title>
      <description>&lt;P&gt;I was moving a Rails 2 app up to Rails 3 and, because I have PostgreSQL installed in a non-standard location on my server, I ran into problems when bundler was trying to install the &lt;code&gt;pg&lt;/code&gt; gem.  After fiddling about for a bit I ended up with this in my &lt;code&gt;config/deploy.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;
require 'bundler/capistrano'

task :set_config_for_pg_gem, :roles =&gt; [:app, :db] do
  run "cd #{current_path} &amp;&amp; bundle config build.pg --with-pg-config=/usr/local/pgsql/bin/pg_config --no-rdoc --no-ri"
end

before "bundle:install", :set_config_for_pg_gem
&lt;/pre&gt;

&lt;p&gt;This sets up the appropriate command line flags for the &lt;code&gt;pg&lt;/code&gt; gem so that they're in place when Capistrano runs the &lt;code&gt;bundle:install&lt;/code&gt; task.  The &lt;code&gt;--no-rdoc --no-ri&lt;/code&gt; part isn't necessary, but I figured it'll save a second or two.  Note that these flags end up in the deploy user's home directory on the server:&lt;/p&gt;

&lt;pre&gt;
$ cat ~/.bundle/config 
--- 
BUNDLE_BUILD__PG: --with-pg-config=/usr/local/pgsql/bin/pg_config --no-rdoc --no-ri
&lt;/pre&gt;

&lt;p&gt;Running this task every time you deploy is a little wasteful since it sets the configuration unnecessarily - really you just need it before the first time you deploy.  So you could optimize things by touching a file in &lt;code&gt;shared/system/&lt;/code&gt; or some such and checking it as part of this task.&lt;/p&gt;

</description>
      <pubDate>Thu, 16 Sep 2010 21:54:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:6e67f02b-b4e8-4098-a61c-82f3d0be8af4</guid>
      <comments>http://railsonpostgresql.com/2010/09/16/rails-3-bundler-and-the-pg-gem#comments</comments>
      <link>http://railsonpostgresql.com/2010/09/16/rails-3-bundler-and-the-pg-gem</link>
    </item>
    <item>
      <title>Rails and PostgreSQL job at Paperless Post</title>
      <description>&lt;p&gt;Another Rails and PostgreSQL job, this time at &lt;a href="http://jobs.github.com/positions/3fb1b2e6-a36e-11df-9f2e-819013ea526f"&gt;Paperless Post&lt;/a&gt; (via the Github jobs board).  Looks like they have a &lt;a href="http://www.paperlesspost.com/info/about/open_positions"&gt;few more open positions&lt;/a&gt;.  And you'd work with &lt;a href="http://www.quirkey.com/blog/"&gt;Aaron Quint&lt;/a&gt;, who's their CTO.  Good times!

</description>
      <pubDate>Tue, 10 Aug 2010 13:17:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:7ab37c59-16d6-4fe4-b181-bcaaeec5bda5</guid>
      <comments>http://railsonpostgresql.com/2010/08/10/rails-and-postgresql-job-at-paperless-post#comments</comments>
      <link>http://railsonpostgresql.com/2010/08/10/rails-and-postgresql-job-at-paperless-post</link>
    </item>
    <item>
      <title>Rails and PostgreSQL job at elevenlearning.com</title>
      <description>Saw this ad for a &lt;a href="http://railswork.com/jobs/1332-rails-developer-for-educational-publishing-startup-pt-ft-early-stage"&gt;Rails and PostgreSQL job&lt;/a&gt; at &lt;a href="http://www.elevenlearning.com/"&gt;Eleven Learning&lt;/a&gt;.  The &lt;a href="http://blog.elevenlearning.com/2010/07/30/we-were-going-to-call-it-compuglobalhypermeganet-learning/"&gt;company name is a "Spinal Tap" reference&lt;/a&gt;... well played.

</description>
      <pubDate>Fri, 06 Aug 2010 09:33:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:2250efb4-892f-4d97-ac49-a4f61ae1adbf</guid>
      <comments>http://railsonpostgresql.com/2010/08/06/rails-and-postgresql-job-at-elevenlearning-com#comments</comments>
      <link>http://railsonpostgresql.com/2010/08/06/rails-and-postgresql-job-at-elevenlearning-com</link>
    </item>
    <item>
      <title>PGCon 2010 talk on Rails and PostgreSQL</title>
      <description>&lt;p&gt;A while back I posted a link to &lt;A href="http://railsonpostgresql.com/2009/08/28/sf-pug-video-postgresql-for-high-performance-rails-apps"&gt;a talk by Gleb Arshinov&lt;/a&gt; that he gave at the SF PUG.  This talk was on "PostgreSQL for high performance Rails apps", and was full of fine suggestions from their experiences with their Rails apps.&lt;/p&gt;

&lt;p&gt;Gleb is back again, this time on May 21 2010 at PGCon where he and Alexander Dymo talked about &lt;a href="http://fosslc.org/drupal/content/postgresql-secret-weapon-high-performance-ruby-rails-applications"&gt;PostgreSQL as a secret weapon for Rails apps&lt;/a&gt;.  Some of the same ground is covered (use SQL DDL vs ActiveRecord &lt;code&gt;create_table&lt;/code&gt;, etc), but there's lots of new information too.  Here are some notes:&lt;/p&gt;

&lt;ul&gt;
&lt;br/&gt;&lt;li&gt;1:10 They're using PostgreSQL 8.4, nginx, and mongrel&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;4:00-6:00 Talks about dropping down into SQL via ActiveRecord&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;6:30 Use &lt;code&gt;include&lt;/code&gt; to eliminate N+1 queries.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;7:30 Watch for things like &lt;code&gt;acts_as_tree&lt;/code&gt; that reintroduce lots of queries in exchange for the improvement in abstraction.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;9:00 One query, 12 joins - complicated, but query time goes from 8 seconds to 60 ms.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;14:00-17:00 A technique for recording SQL queries; this helps ensure you're not running unexpected queries&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;19:00 Suggests use straight SQL for DDL rather than the ActiveRecord DSL&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;20:00 Use constraints, FKs, etc to preserve data integrity - "anything you don't have a constraint on will get corrupted"&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;23:00 Don't use &lt;code&gt;CASCADE&lt;/code&gt; since app won't know about the deletions&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;28:00 Keep a log of times for the most frequent user requests.  Alex suggests using integration tests for this; code is at 29:10 and 29:30.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;32:30 A technique for loading data with ActiveRecord's &lt;code&gt;select&lt;/code&gt; option with PostgreSQL arrays to save on object creation.  Questions from the audience about normalization vs efficiency.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;38:50 Role/user/privilege checking can be slow; shows a technique for using PostgreSQL's &lt;code&gt;bool_or&lt;/code&gt; and &lt;code&gt;GROUP BY&lt;/code&gt; to get the data in one fell swoop.  Query time went from 2+ seconds to 64 ms.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;42:00 Do analytics in the database.  Saw speed improve from 90s to 5s and saved tons of RAM.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;44:40 Some excellent new PostgreSQL features that are either here now or are on the way (replication, windowing functions)&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;46:30 Demonstrates a problem with PostgreSQL's &lt;code&gt;LIMIT&lt;/code&gt; and &lt;code&gt;OFFSET&lt;/code&gt; when used with subselects.  Some discussion of pagination with the audience.  Here's an excellent discussion of &lt;a href="http://justinfrench.com/notebook/pagination-alternatives"&gt;pagination alternatives&lt;/a&gt; written by Justin French.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;50:30 How to force PostgreSQL to use a subselect vs a join; the example goes from 605ms to 325 ms.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;52:20 Be careful with &lt;code&gt;generate_series&lt;/code&gt;.  Apparently these functions cannot generate hints for the planner.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;55:30 General props to PostgreSQL community.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;59:40 Need to test queries both in cold state and hot state; they saw 14x speed difference.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;1:01:40 Tune PostgreSQL - shared_buffers, work_mem, autovacuum, etc.  Rely on community knowledge for initial configuration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lots of good stuff there, enjoy!&lt;/p&gt;



</description>
      <pubDate>Tue, 03 Aug 2010 17:04:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:eb9664aa-77a4-4b7c-8fbb-19160687a728</guid>
      <comments>http://railsonpostgresql.com/2010/08/03/pgcon-2010-talk-on-rails-and-postgresql#comments</comments>
      <link>http://railsonpostgresql.com/2010/08/03/pgcon-2010-talk-on-rails-and-postgresql</link>
    </item>
    <item>
      <title>Pivotal Labs Talk - Scaling a Rails App with Postgres</title>
      <description>I'm slowly catching up with my podcast backlog and came across a Pivotal Labs talk from May 2009.  In this talk Josh Susser and Damon McCormick are presenting on &lt;a href="http://pivotallabs.com/talks/67-scaling-a-rails-app-with-postgres"&gt;Scaling a Rails App with Postgres&lt;/a&gt; .  It's a little dated now - this talk was given was when PostgreSQL 8.4 was in beta - but, still, lots of good stuff.  Here are some notes:

&lt;ul&gt;
&lt;li&gt;They started with an existing Rails app with lots of data, so they had some constraints - not greenfield development.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;Around the 5-6 minute mark there's a good discussion of PostgreSQL's query optimizer and how it analyzes a table's data distribution.  One takeaway (mentioned around 16:20) is to run &lt;code&gt;vacuum&lt;/code&gt; more often on a particular table if there are a lot of writes.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;10:00 How to set STATISTICS for a particular table.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;11:00 Using partial indexes.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;14:00 Indexing on expressions.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;18:10-23:00 A nice discussion of the &lt;code&gt;EXPLAIN&lt;/code&gt; output.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;23:45 Here they talk about wide columns.  I've seen this in MySQL as well, where splitting text data out into a separate table yielded some good speedups.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;26:10 Some discussion of &lt;code&gt;pg_bench&lt;/code&gt;.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;30:20 Discusses the PostgreSQL log analyzer &lt;a href="http://pgfouine.projects.postgresql.org/"&gt;pgFouine&lt;/a&gt;.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;35:30 How long does it take to add an index to large tables?  They saw times of up to an hour for tables with millions of rows.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;36:30 clustering your data in order to get PostgreSQL to write it more efficiently.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;37:30-48:00 A thorough discussion of partitioning tables via table inheritance.  They used an ActiveRecord model (39:23) with a bunch of utility methods.  They also had a cron to periodically create new partitions.  At 45:15 they make a nice distinction between using partial indexes and partitions - one advantage is that a partition's indexes can be different than its parents indexes.  At 49:00 they mention maybe doing a plugin, not sure if that happened.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;52:00 Some discussion of full text search via &lt;code&gt;tsearch&lt;/code&gt;.&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;53:00 PostgreSQL's lack of built in replication outside of WAL shipping, Slony, etc.  Thank goodness 9.0 will address this!&lt;/li&gt;
&lt;br/&gt;&lt;li&gt;54:00 Some props to &lt;a href="http://www.engineyard.com/"&gt;Engine Yard&lt;/a&gt; on their PostgreSQL support.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good stuff all around, and thanks to Pivotal for posting these great talks!&lt;/p&gt;

</description>
      <pubDate>Fri, 23 Jul 2010 21:01:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:b0a28280-725e-4611-8081-110f798efcf1</guid>
      <comments>http://railsonpostgresql.com/2010/07/23/pivotal-labs-talk-scaling-a-rails-app-with-postgres#comments</comments>
      <link>http://railsonpostgresql.com/2010/07/23/pivotal-labs-talk-scaling-a-rails-app-with-postgres</link>
    </item>
    <item>
      <title>Intro to PostGIS</title>
      <description>&lt;p&gt;If you are planning on building a Rails application that uses spatial data in any way, then you owe it to yourself to take the time to investigate Postgis.  Out of the box you&amp;#8217;ll be able to perform an array of powerful functions on your spatial data: from bounding boxes and distance queries to polygon area calculations.&lt;/p&gt;

&lt;h2&gt;Installation&lt;/h2&gt;

&lt;p&gt;I won&amp;#8217;t go into setup in too much detail, under most linux distributions postgis is a simple package install, it&amp;#8217;s in macports if you&amp;#8217;re a mac user, so either way installation shouldn&amp;#8217;t be too hard.  For integration with rails I recommend the GeoRuby gem and spatial_adapter.  From the docs: &amp;#8220;GeoRuby provides data types intended to hold data returned from PostGIS&amp;#8230;&amp;#8221;.  spatial adapter is a rails plugin that extends ActiveRecord so that it understands geometric columns, transparently converting them to subclasses of the GeoRuby::Geometry class, supporting geometry columns in migrations, etc.  spatial_adapter is hosted on github: http://github.com/fragility/spatial_adapter.&lt;/p&gt;

&lt;h2&gt;Data Storage&lt;/h2&gt;

&lt;p&gt;Postgis supports &lt;a href="http://postgis.refractions.net/documentation/manual-1.3/ch04.html#RefObject"&gt;lots&lt;/a&gt; of datatypes.  For the purpose of this blog post we&amp;#8217;ll focus on just using points, all other datatypes are composed of points and most of the concepts are easily applied to the other datatypes.  Points are made up of at least three points of data: x, y, and Spatial Reference System Identifier (SRID).  &lt;a href="http://en.wikipedia.org/wiki/SRID"&gt;SRIDs&lt;/a&gt; are used to describe the coordinate system used by the point.  My gis background is poor so I&amp;#8217;ll just suggest that if  you are planning on working in lat/long values, SRID 4269 is probably the right choice for you (or maybe 4326, see the comments).  The one downside of using lat/long data is it makes distance queries more difficult, 1 degree isn&amp;#8217;t a fixed number of meters so you can&amp;#8217;t directly ask the database for all rows within 100 meters of a given point, or at least not without having the database run a sequential scan of all rows.  If people are interested in distance queries I&amp;#8217;m happy to write about the subject.&lt;/p&gt;

&lt;h2&gt;Queries&lt;/h2&gt;

&lt;p&gt;The most basic query is the bounding box - which geometries lay within the given box?  It is defined in postgis as &lt;code&gt;&amp;&amp;&lt;/code&gt; and is able to use spatial indexes directly so is very fast.  Beyond that most queries take the form of a function and are well documented in the &lt;a href="http://postgis.refractions.net/documentation/"&gt;PostGIS documentation&lt;/a&gt;, but enough talk - let&amp;#8217;s start an example.&lt;/p&gt;

&lt;h2&gt;Example&lt;/h2&gt;

&lt;p&gt;Let&amp;#8217;s assume we have a table of restaurants that we want to display on a map. First let&amp;#8217;s add a geometry column to the restaurants table, with spatial_adapter it is a simple migration:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
add_column :restaurants, :the_geom, :point, :srid =&gt; 4269&lt;br /&gt;
add_index :restaurants, :the_geom, :spatial =&gt; true
&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;If you open up a psql console and look at the table definition you will see that this adds the column the_geom with the type the_geom as well as adding three new table constraints: srid=4269, number of dimensions is 2 (postgis supports more), and the geometry type is a point.  Handy!  You can see we&amp;#8217;ve also added an index, spatial_adapter adds the :spatial option to indexes to specify simplify the creation of spatial indexes.&lt;/p&gt;

&lt;p&gt;Now to add points let&amp;#8217;s open up a console and add geometry data to our restaurants:&lt;/p&gt;

&lt;p&gt;&lt;code&gt; r = Resaurant.first r.the_geom = Point.from_x_y(-122.39, 47.5123, 4269) r.save! &lt;/code&gt;  &lt;/p&gt;

&lt;p&gt;Of course in real life you aren&amp;#8217;t going to just make up data, you&amp;#8217;ll likely want to use a geocoding service like &lt;a href="http://code.google.com/apis/maps/documentation/geocoding/"&gt;google&amp;#8217;s geocoding api&lt;/a&gt; to determine the correct lat/long information.  You&amp;#8217;ll probably also want to store your chosen SRID in a constant somewhere, but now I&amp;#8217;m nitpicking - let&amp;#8217;s looks query our new data.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
Restaurant.first(:conditions =&gt; ["the_geom &amp;amp;&amp;amp; ?", Polygon.from_coordinates([[[x_min, y_min], [x_min, y_max], [x_max, y_max], [x_max, y_min], [x_min, y_min]]], 4269)])
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Simple!  Hope this helps show the basics of using PostGIS with rails.  This post just barely scrapes the surface, luckily PostGIS and GeoRuby have excellent documentation, but if you have any more questions don&amp;#8217;t hesitate to ask in the comments and I&amp;#8217;ll try and help.&lt;/p&gt;

&lt;p style="font-size: 10px"&gt;Doug Cole is the CTO of &lt;a href="http://www.estately.com"&gt;www.estately.com&lt;/a&gt; a real estate search website. Interested in working with Estately?  &lt;a href="http://www.estately.com/about/contact_us"&gt;Let us know!&lt;/a&gt; &lt;/p&gt;</description>
      <pubDate>Thu, 05 Nov 2009 01:25:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:b771c611-379d-4fcd-b598-075bf7c5ffa6</guid>
      <comments>http://railsonpostgresql.com/2009/11/05/intro-to-postgis#comments</comments>
      <link>http://railsonpostgresql.com/2009/11/05/intro-to-postgis</link>
    </item>
    <item>
      <title>Rails and PostgreSQL job in Honolulu</title>
      <description>&lt;p&gt;Saw this advertisement for a &lt;a href="http://telecommutejoblist.com/ruby-rails-developer-honolulu"&gt;Ruby/Rails/PostgreSQL job in Honolulu&lt;/a&gt; today.   It's for &lt;a href="http://eggup.com/"&gt;eggup.com&lt;/a&gt;, which unfortunately is completely protected by a HTTP basic authentication challenge.   First thing to do if you get that job - put up a &lt;a href="http://line25.com/articles/tips-for-designing-an-awesome-coming-soon-page"&gt;nice "coming soon" page&lt;/a&gt;!&lt;/p&gt;

</description>
      <pubDate>Tue, 03 Nov 2009 18:20:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:437c4183-85ee-4c37-a159-3a9be7599449</guid>
      <comments>http://railsonpostgresql.com/2009/11/03/rails-and-postgresql-job-in-honolulu#comments</comments>
      <link>http://railsonpostgresql.com/2009/11/03/rails-and-postgresql-job-in-honolulu</link>
    </item>
    <item>
      <title>RailsOnPg by Alexander Tretyakov</title>
      <description>&lt;p&gt;Thanks to &lt;a href="http://www.robbyonrails.com/articles/2009/10/21/railsonpg-released"&gt;Robby on Rails&lt;/a&gt; I heard about Alexander Tretyakov's interesting &lt;a href="http://github.com/alex3t/rails_on_pg"&gt;RailsOnPg&lt;/a&gt; plugin.   This plugin makes it a bit easier to create PostgreSQL functions, triggers, views, and foreign keys by providing a nicer front end to calls to &lt;code&gt;ActiveRecord::Base.connection.execute&lt;/code&gt;.&lt;/p&gt; 

&lt;p&gt;For example, here's a migration to add a foreign key to a &lt;code&gt;Comment&lt;/code&gt; model that belongs to a &lt;code&gt;User&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;
class AddForeignKeyFromCommentsToUsers &lt; ActiveRecord::Migration 
  def self.up
    add_foreign_key :comments, :user_id, :users
  end
  def self.down
    remove_foreign_key :comments, :user_id, :users
  end
end
&lt;/pre&gt;

&lt;p&gt;This results in the following SQL:&lt;/p&gt;

&lt;pre&gt;
ALTER TABLE comments
                 ADD CONSTRAINT fk_comments_user_id
                 FOREIGN KEY (user_id)
                 REFERENCES users(id) 
                 ON UPDATE NO ACTION 
                 ON DELETE NO ACTION 
&lt;/pre&gt;

&lt;p&gt;As you can see, this provides some sensible defaults and a consistent naming scheme so that you can reliably roll back a migration that created a foreign key.&lt;/p&gt;

&lt;p&gt;I ran into some problems when creating a function; my migration failed with a &lt;code&gt;PGError&lt;/code&gt;.  Turns out that the plugin attempts to execute &lt;code&gt;CREATE LANGUAGE plpgsql&lt;/code&gt; before it creates a function; in my case that language was already in place.  I commented out line 16 of &lt;code&gt;railsonpg/lib/functions.rb&lt;/code&gt; (the call to &lt;code&gt;setlang&lt;/code&gt;) and everything worked fine.  It looks like this need for a &lt;code&gt;CREATE LANGUAGE IF NOT EXISTS&lt;/code&gt; (or something) has &lt;a href="http://andreas.scherbaum.la/blog/archives/346-create-language-if-not-exist.html"&gt;come up before&lt;/a&gt;, but I'm not sure what the status is.  I'm using PostgreSQL 8.4.1 and that statement doesn't seem to be supported.&lt;/p&gt;

&lt;p&gt;At any rate, this looks like a handy plugin that could remove a lot of raw SQL from your migrations.  Good stuff!&lt;/p&gt;

</description>
      <pubDate>Fri, 23 Oct 2009 00:39:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:fc00f839-ddd0-4e2f-a214-dbc6f1a6dc46</guid>
      <comments>http://railsonpostgresql.com/2009/10/23/railsonpg-by-alexander-tretyakov#comments</comments>
      <link>http://railsonpostgresql.com/2009/10/23/railsonpg-by-alexander-tretyakov</link>
    </item>
  </channel>
</rss>
