<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/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>Robby on Rails: Rails Migrations and PostgreSQL Constraints</title>
    <link>http://www.robbyonrails.com/articles/2005/11/11/rails-migrations-and-postgresql-constraints</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>thoughts.sort_by{|t| t[:topic]}.collect </description>
    <item>
      <title>Rails Migrations and PostgreSQL Constraints</title>
      <description>&lt;p&gt;A question was posed on the Rails mailing list concerning how one would go about adding CONSTRAINTs to the database tables with &lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/Migration.html"&gt;ActiveRecord::Migration&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;One argument was raised stating that it is easier to handle these in plain &lt;span class="caps"&gt;SQL&lt;/span&gt; schema files. I disagree. :-)&lt;/p&gt;


	&lt;h3&gt;Migrations to the Rescue&lt;/h3&gt;


	&lt;p&gt;Databases evolve and I have recently found the Migration structure to be perfect for handling iterations and schema changes. Using the &lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html#M000529"&gt;#execute&lt;/a&gt; method has helped move more of my code into the Ruby/Rails framework&amp;#8230; and that just makes things easier to manage in the long-run. This is the approach that we are using at &lt;a href="http://www.planetargon.com/development.html"&gt;&lt;span class="caps"&gt;PLANET ARGON&lt;/span&gt;&lt;/a&gt; with some of our current client projects.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;# db/migrate/6_add_foreign_key.rb&lt;/span&gt;
&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;AddForeignKey&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Migration&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;self.up&lt;/span&gt;
    &lt;span class="ident"&gt;execute&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;ALTER TABLE bees ADD CONSTRAINT beehive_id_fkey FOREIGN KEY
(beehive_id) REFERENCES beehives (id);&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;self.down&lt;/span&gt;
    &lt;span class="ident"&gt;execute&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;ALTER TABLE bees DROP CONSTRAINT beehive_id_fkey;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;This gives us an easy way to use the standard, &lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#M000507"&gt;#create_table&lt;/a&gt; syntax for building our tables with Ruby&amp;#8230; and then we can slap these constraints on later.&lt;/p&gt;


	&lt;p&gt;This would add the constraints&amp;#8230;&lt;/p&gt;


&lt;code&gt;
&lt;pre&gt;
rake migrate VERSION=6
&lt;/pre&gt;
&lt;/code&gt;

...run tests&amp;#8230;
&lt;code&gt;
&lt;pre&gt;
rake
&lt;/pre&gt;
&lt;/code&gt;

...roll back&amp;#8230;
&lt;code&gt;
&lt;pre&gt;
rake migrate VERSION=5
&lt;/pre&gt;
&lt;/code&gt;

	&lt;p&gt;I have found that this approach is really useful with testing in Rails. When I think that I have everything working great (without &lt;span class="caps"&gt;CONSTRAINTS&lt;/span&gt; in PostgreSQL), I run another migration to add a bunch of foreign key and data constraints to the tables and&amp;#8230; run my tests again.&lt;/p&gt;


	&lt;h3&gt;Let&amp;#8217;s give Active Record a Hug&lt;/h3&gt;


	&lt;p&gt;This has helped me &lt;a href="http://www.robbyonrails.com/articles/2005/09/27/the-bitter-sweet-taste-of-agnostic-database-schemas"&gt;gain some trust&lt;/a&gt; in Active Record while still giving me that comforting feeling that &lt;a href="http://www.postgresql.org"&gt;PostgreSQL&lt;/a&gt; is acting as the &lt;em&gt;body guard for my data&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;Even if you don&amp;#8217;t end up using Migrations to handle these types of database schema changes, I would highly suggest that you model your implementation after this. I&amp;#8217;ve worked with many database schemas and this just makes it easy to add your new change and run one command to commit it to the database.&lt;/p&gt;


	&lt;p&gt;...and now I go play with beehives&amp;#8230;&lt;/p&gt;
</description>
      <pubDate>Fri, 11 Nov 2005 10:42:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:f125682d520f030e69dadb4be8913ebe</guid>
      <author>Robby Russell</author>
      <link>http://www.robbyonrails.com/articles/2005/11/11/rails-migrations-and-postgresql-constraints</link>
      <category>Ruby on Rails</category>
      <category>Programming</category>
      <category>rails</category>
      <category>postgresql</category>
      <category>migrations</category>
      <category>database</category>
      <category>activerecord</category>
    </item>
  </channel>
</rss>
