<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Datamapper.org News and Notes</title>
  <subtitle>Ruby Object Relational Mapper</subtitle>
  <id>http://www.datamapper.org</id>
  <generator uri="http://jekyllrb.com/" version="0.5">Jekyll</generator>
  <link href="http://www.datamapper.org/news.rss" rel="self"/>
  <link href="http://www.datamapper.org/"/>
  <updated>2010-07-18T15:10:39-07:00</updated>
  <author>
    <name>Maintained By the Community</name>
    <email>datamapper@googlegroups.com</email>
  </author>

  
  <entry>
    <title>DataMapper 1.0 released</title>
    <link href="http://datamapper.org/articles/datamapper-100-released.html"/>
    <updated>2010-06-12T00:00:00-07:00</updated>
    <id>tag:datamapper.org,2010-06-12</id>
    <content type="html">&lt;h1 id='datamapper_10_released'&gt;DataMapper 1.0 released&lt;/h1&gt;

&lt;p&gt;&lt;a href='http://github.com/datamapper/dm-core/tree/v1.0.0'&gt;DataMapper 1.0 (Vermouth)&lt;/a&gt; was released earlier this week, coinciding with &lt;a href='http://twitter.com/dbussink'&gt;Dirkjan Bussink&lt;/a&gt;&amp;#8217;s &lt;a href='http://en.oreilly.com/rails2010/public/schedule/detail/14198'&gt;presentation at Railsconf 2010&lt;/a&gt; (&lt;a href='http://www.slideshare.net/dbussink/datamapper-railsconf2010'&gt;his slides are posted&lt;/a&gt; as well).&lt;/p&gt;

&lt;p&gt;The transition from the 0.10.x series to 1.0 does involve several changes regarding how users will interact with DataMapper. Unfortunately we have no had time to update all of our documentation on the site, so please bear with us while we get everything in order. Read on for further details regarding these changes, and users are always welcome in #datamapper on irc.freenode.net and we strive to any answer questions promptly.&lt;/p&gt;

&lt;p&gt;Thank you to everyone in the community, especially this mailing list and the IRC channel. There&amp;#8217;s no way we could&amp;#8217;ve reached this milestone without your encouragement and assistance. It&amp;#8217;s extremely rewarding to see DM hit 1.0, but at the same time it also sets a baseline for future development to build on. In some ways we&amp;#8217;re only just getting started, the future we have planned for DM is even more ambitious.&lt;/p&gt;

&lt;h2 id='before_you_install'&gt;Before you install&lt;/h2&gt;

&lt;p&gt;The installation process for DM 1.0 is pretty similar to what it was previously in 0.10.x and 0.9.x with a few exceptions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Using auto-migration and auto-upgrading require dm-migrations rather than just dm-core. The reason for this is that dm-migrations should share a lot of code with auto-migrations, but they don’t, and in an attempt to DRY things up we’ve centralized all the code in one package and will begin refactoring the code over the coming months.&lt;/li&gt;

&lt;li&gt;Transactions require the use of the dm-transactions gem.&lt;/li&gt;

&lt;li&gt;It is no longer necessary to gem install data_objects or any do_* gem directly. Each DO based adapter has been extracted into their own gems, and installing them will setup the dependencies on dm-core and the appropriate DO gem(s). The new adapters are:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;dm-sqlite-adapter&lt;/li&gt;

&lt;li&gt;dm-postgres-adaper&lt;/li&gt;

&lt;li&gt;dm-mysql-adapter&lt;/li&gt;

&lt;li&gt;dm-oracle-adapter&lt;/li&gt;

&lt;li&gt;dm-sqlserver-adapter&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='installation'&gt;Installation&lt;/h2&gt;

&lt;p&gt;Install dm-core:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ gem install dm-core&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The next thing you want to do is decide which adapter you want to use. For example if you want to use sqlite, do:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ gem install dm-sqlite-adapter&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This should pull in data_objects and do_sqlite3 automatically, so no need to specify either of those explicitly anymore. It’s likely you’ll want to use migrations (for classic or auto-migrations), and transactions when using sqlite, so to install them do:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ gem install dm-migrations dm-transactions&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;There is also a metagem which combines several gems into a single package:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ gem install data_mapper&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This pulls a nice base stack for DM development. The gems included are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dm-core&lt;/li&gt;

&lt;li&gt;dm-aggregates&lt;/li&gt;

&lt;li&gt;dm-constraints&lt;/li&gt;

&lt;li&gt;dm-migrations&lt;/li&gt;

&lt;li&gt;dm-transactions&lt;/li&gt;

&lt;li&gt;dm-serializer&lt;/li&gt;

&lt;li&gt;dm-timestamps&lt;/li&gt;

&lt;li&gt;dm-validations&lt;/li&gt;

&lt;li&gt;dm-types&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So putting this all together you can do:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ gem install data_mapper dm-sqlite-adapter&lt;/code&gt;&lt;/p&gt;

&lt;h2 id='changes'&gt;Changes&lt;/h2&gt;

&lt;p&gt;A lot of tickets have been addressed during the release candidate cycle and you can refer to the earlier RC notes for change details (&lt;a href='http://datamapper.org/articles/datamapper-100_rc2_released.html'&gt;RC2&lt;/a&gt;, &lt;a href='http://datamapper.org/articles/datamapper-100_rc3_released.html'&gt;RC3&lt;/a&gt;). You should also refer to the list of 61 tickets we&amp;#8217;ve resolved for the 1.0 milestone:&lt;/p&gt;

&lt;p&gt;&lt;a href='http://datamapper.lighthouseapp.com/projects/20609/milestones/62234-0103'&gt;http://datamapper.lighthouseapp.com/projects/20609/milestones/62234-0103&lt;/a&gt;&lt;/p&gt;

&lt;h2 id='how_to_report_issues'&gt;How to report issues&lt;/h2&gt;

&lt;p&gt;Please report any issues you find in IRC, on the mailing list, or inthe tracker:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='irc://irc.freenode.net/#datamapper'&gt;IRC&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://groups.google.com/group/datamapper'&gt;Mailing List&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://datamapper.lighthouseapp.com/projects/20609-datamapper'&gt;Bug Tracker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry>
  
  <entry>
    <title>DataMapper 1.0.0 rc3 released</title>
    <link href="http://datamapper.org/articles/datamapper-100_rc3_released.html"/>
    <updated>2010-05-27T00:00:00-07:00</updated>
    <id>tag:datamapper.org,2010-05-27</id>
    <content type="html">&lt;h1 id='datamapper_100_rc3_released'&gt;DataMapper 1.0.0 rc3 released&lt;/h1&gt;

&lt;p&gt;Today I released DataMapper 1.0.0 rc3. It includes several bugs fixes for issues found in rc2, as well as a few other tickets in the queue.&lt;/p&gt;

&lt;h2 id='how_do_i_install_rc3'&gt;How do I install rc3?&lt;/h2&gt;

&lt;p&gt;Since the installation process is pretty similar to rc2, I&amp;#8217;m going to give you the abbreviated version. &lt;a href='http://bit.ly/dC7U1p'&gt;Click here&lt;/a&gt; if you would like to see the release notes.&lt;/p&gt;

&lt;p&gt;1) Install dm-core:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nv'&gt;$ &lt;/span&gt;gem install dm-core --pre
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;2) Install an adapter:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nv'&gt;$ &lt;/span&gt;gem install dm-sqlite-adapter --pre
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;3a) Install supporting gems:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nv'&gt;$ &lt;/span&gt;gem install dm-migrations dm-transactions --pre
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;3b) OR install a metagem with several well tested supporting gems:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nv'&gt;$ &lt;/span&gt;gem install data_mapper --pre
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This pulls a nice base stack for DM development. The gems included are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dm-core&lt;/li&gt;

&lt;li&gt;dm-aggregates&lt;/li&gt;

&lt;li&gt;dm-constraints&lt;/li&gt;

&lt;li&gt;dm-migrations&lt;/li&gt;

&lt;li&gt;dm-transactions&lt;/li&gt;

&lt;li&gt;dm-serializer&lt;/li&gt;

&lt;li&gt;dm-timestamps&lt;/li&gt;

&lt;li&gt;dm-validations&lt;/li&gt;

&lt;li&gt;dm-types&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Or use this one-liner to install everything in one go:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nv'&gt;$ &lt;/span&gt;gem install data_mapper dm-sqlite-adapter --pre
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h2 id='whats_changed'&gt;What&amp;#8217;s changed?&lt;/h2&gt;

&lt;p&gt;To see more information about the tickets we&amp;#8217;ve closed since 0.10.2 check out the &lt;a href='http://bit.ly/b4yVl3'&gt;current milestone status&lt;/a&gt; on Lighthouse.&lt;/p&gt;

&lt;h2 id='how_to_report_issues'&gt;How to report issues&lt;/h2&gt;

&lt;p&gt;Please report any issues you find in IRC, on the mailing list, or in the tracker:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='irc://irc.freenode.net/#datamapper'&gt;IRC&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://groups.google.com/group/datamapper'&gt;Mailing List&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://datamapper.lighthouseapp.com/projects/20609-datamapper'&gt;Bug Tracker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry>
  
  <entry>
    <title>DataMapper 1.0.0 rc2 released</title>
    <link href="http://datamapper.org/articles/datamapper-100_rc2_released.html"/>
    <updated>2010-05-20T00:00:00-07:00</updated>
    <id>tag:datamapper.org,2010-05-20</id>
    <content type="html">&lt;h1 id='datamapper_100_rc2_released'&gt;DataMapper 1.0.0 rc2 released&lt;/h1&gt;

&lt;p&gt;I just wanted to give you the heads up that we&amp;#8217;ve just released DataMapper 1.0.0 rc2.&lt;/p&gt;

&lt;p&gt;With RailsConf coming up, and the launch of DM 1.0, we are starting the RC process now to make sure the installation process is solid and that the API is stable beforehand.&lt;/p&gt;

&lt;h2 id='installation_changes'&gt;Installation Changes&lt;/h2&gt;

&lt;p&gt;The installation process for DM 1.0 is pretty similar to what it was previously in 0.10.x and 0.9.x with a few exceptions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Using auto-migration and auto-upgrading require dm-migrations rather than just dm-core. The reason for this is that dm-migrations &lt;em&gt;should&lt;/em&gt; share alot of code with auto-migrations, but they don&amp;#8217;t, and in an attempt to DRY things up we&amp;#8217;ve centralized all the code in one package and will begin refactoring the code over the coming months.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;Transactions require the use of the dm-transactions gem.&lt;/p&gt;
&lt;/li&gt;

&lt;li&gt;
&lt;p&gt;It is no longer necessary to gem install data_objects or any do_* gem directly. Each DO based adapter has been extracted into their own gems, and installing them will setup the dependencies on dm-core and the appropriate DO gem(s). The new adapters are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dm-sqlite-adapter&lt;/li&gt;

&lt;li&gt;dm-postgres-adaper&lt;/li&gt;

&lt;li&gt;dm-mysql-adapter&lt;/li&gt;

&lt;li&gt;dm-oracle-adapter&lt;/li&gt;

&lt;li&gt;dm-sqlserver-adapter&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id='how_do_i_install_the_rc'&gt;How do I install the RC?&lt;/h2&gt;

&lt;p&gt;The first step is to make sure you&amp;#8217;ve installed extlib 0.9.15:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nv'&gt;$ &lt;/span&gt;gem install extlib -v0.9.15
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Note that this will go away in the next RC. I forgot to add extlib 0.9.15 as a dependency for rc2, which is why it&amp;#8217;s required explicitly at the moment.&lt;/p&gt;

&lt;p&gt;Since this is a prerelease gem you have to install dm-core with the &amp;#8211; pre option, eg:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nv'&gt;$ &lt;/span&gt;gem install dm-core --pre
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If you don&amp;#8217;t specify &amp;#8211;pre, rubygems will download the last stable version of DM, which is 0.10.2.&lt;/p&gt;

&lt;p&gt;The next thing you want to do is decide which adapter you want to use. For example if you want to use sqlite, do:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nv'&gt;$ &lt;/span&gt;gem install dm-sqlite-adapter --pre
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This should pull in data_objects and do_sqlite3 automatically, so no need to specify either of those explicitly anymore.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s likely you&amp;#8217;ll want to use migrations (for classic or auto- migrations), and transactions when using sqlite, so to install them do:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nv'&gt;$ &lt;/span&gt;gem install dm-migrations dm-transactions --pre
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;There is also a metagem which combines several gems into a single package:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nv'&gt;$ &lt;/span&gt;gem install data_mapper --pre
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This pulls a nice base stack for DM development. The gems included are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://github.com/datamapper/dm-core'&gt;dm-core&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://github.com/datamapper/dm-aggregates'&gt;dm-aggregates&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://github.com/datamapper/dm-constraints'&gt;dm-constraints&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://github.com/datamapper/dm-migrations'&gt;dm-migrations&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://github.com/datamapper/dm-transactions'&gt;dm-transactions&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://github.com/datamapper/dm-serializer'&gt;dm-serializer&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://github.com/datamapper/dm-timestamps'&gt;dm-timestamps&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://github.com/datamapper/dm-validations'&gt;dm-validations&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://github.com/datamapper/dm-types'&gt;dm-types&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So putting this all together you can do:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nv'&gt;$ &lt;/span&gt;gem install extlib -v0.9.15
&lt;span class='nv'&gt;$ &lt;/span&gt;gem install data_mapper dm-sqlite-adapter --pre
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Again, the extlib installation step will not be necessary in the next RC.&lt;/p&gt;

&lt;h2 id='what_are_the_changes'&gt;What are the changes?&lt;/h2&gt;

&lt;p&gt;There are alot of internal refactorings, some bug fixes, but for the most part 1.0.0 should be quite similar to 0.10.2. We decided to launch 1.0 because DM has been in a relatively stable state for the last 6 months, and there aren&amp;#8217;t any really major API changes left. Anything that&amp;#8217;s planned are more additions rather than changes to existing functionality, so we decided it was better to freeze the current API at 1.0 and release for RailsConf.&lt;/p&gt;

&lt;p&gt;There are some simplifications in the Property/Type API you should be aware of. Some custom types you have may require slight modifications to work with 1.0.0 rc2. Piotr Solnica will be posting some information about how to do the modification, but for now look at the Property subclasses in dm-types as well as inside dm-core to get an idea of how it works.&lt;/p&gt;

&lt;p&gt;As mentioned, the other large change is how auto-migrations have been moved to dm-migrations, as well as transactions to dm-transactions. The main reason we moved those from the core is that only a small fraction of DM adapters support migrations and transactions, and it didn&amp;#8217;t seem right for the core layer to know anything about those concerns. I felt that having them in a separate package allows us to eliminate some duplcation (in the case of migrations), and ensure transactions gets more attention than if it was part of core.&lt;/p&gt;

&lt;h2 id='where_was_rc1'&gt;Where was rc1?&lt;/h2&gt;

&lt;p&gt;You might be asking yourself &amp;#8220;where was rc1?&amp;#8221;. Well&amp;#8230; I decided to do a soft launch of the first rc and just announce it to people in the &lt;a href='irc://irc.freenode.net/#datamapper'&gt;#datamapper&lt;/a&gt; IRC channel on freenode. It&amp;#8217;s been a few months since we did any kind of release, and with the new gem organization I wasn&amp;#8217;t sure if we&amp;#8217;d have all the kinks worked out. There was one small issue actually, so we bumped to rc2 and released the same day. We also added the latest DO as a dependency, which has a number of improvements/bug fixes, so I think this was a good thing overall.&lt;/p&gt;

&lt;h2 id='how_to_report_issues'&gt;How to report issues&lt;/h2&gt;

&lt;p&gt;Please report any issues you find in IRC, on the mailing list, or in the tracker:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='irc://irc.freenode.net/#datamapper'&gt;IRC&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://groups.google.com/group/datamapper'&gt;Mailing List&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://datamapper.lighthouseapp.com/projects/20609-datamapper'&gt;Bug Tracker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
  </entry>
  
  <entry>
    <title>DataMapper 0.10.2 is Released</title>
    <link href="http://datamapper.org/articles/datamapper_0102_released.html"/>
    <updated>2009-12-11T00:00:00-08:00</updated>
    <id>tag:datamapper.org,2009-12-11</id>
    <content type="html">&lt;h1 id='datamapper_0102_is_released'&gt;DataMapper 0.10.2 is Released&lt;/h1&gt;

&lt;p&gt;This release adds new Set operations, fixes multiple bugs, and even more of the public API is specced.&lt;/p&gt;

&lt;p&gt;Read the &lt;a href='http://bit.ly/5l5ftv'&gt;Release Announcement&lt;/a&gt; for more info&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>DataMapper at RubyEnRails Amsterdam 2009</title>
    <link href="http://datamapper.org/articles/datamapper-at-rer-2009.html"/>
    <updated>2009-12-07T00:00:00-08:00</updated>
    <id>tag:datamapper.org,2009-12-07</id>
    <content type="html">&lt;h1 id='datamapper_at_rubyenrails_amsterdam_2009'&gt;DataMapper at RubyEnRails Amsterdam 2009&lt;/h1&gt;
&lt;object height='225' width='400'&gt;&lt;param name='allowfullscreen' value='true' /&gt;&lt;param name='allowscriptaccess' value='always' /&gt;&lt;param name='movie' value='http://vimeo.com/moogaloop.swf?clip_id=7643064&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1' /&gt;&lt;embed src='http://vimeo.com/moogaloop.swf?clip_id=7643064&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1' allowfullscreen='true' type='application/x-shockwave-flash' allowscriptaccess='always' height='225' width='400' /&gt;&lt;/object&gt;&lt;p&gt;&lt;a href='http://vimeo.com/7643064'&gt;ReR09 - DirkjanBussink&lt;/a&gt; from &lt;a href='http://vimeo.com/user2623183'&gt;Interbureau Holder&lt;/a&gt; on &lt;a href='http://vimeo.com'&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;At this year&amp;#8217;s &lt;a href='http://2009.rubyenrails.nl/'&gt;RubyEnRails 2009&lt;/a&gt;, Dirkjan Bussink presented the current 0.10.x series of DataMapper and gave a preview of what lies ahead for the 1.0 release.&lt;/p&gt;
&lt;div id='__ss_2390430' style='width:425px;text-align:left'&gt;&lt;a href='http://www.slideshare.net/dbussink/datamapper-2390430' title='DataMapper' style='font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;'&gt;DataMapper&lt;/a&gt;&lt;object height='355' style='margin:0px' width='425'&gt;&lt;param name='movie' value='http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=datamapper-091031084329-phpapp02&amp;stripped_title=datamapper-2390430' /&gt;&lt;param name='allowFullScreen' value='true' /&gt;&lt;param name='allowScriptAccess' value='always' /&gt;&lt;embed src='http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=datamapper-091031084329-phpapp02&amp;stripped_title=datamapper-2390430' allowfullscreen='true' type='application/x-shockwave-flash' allowscriptaccess='always' height='355' width='425' /&gt;&lt;/object&gt;&lt;div style='font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;'&gt;View more &lt;a href='http://www.slideshare.net/' style='text-decoration:underline;'&gt;documents&lt;/a&gt; from &lt;a href='http://www.slideshare.net/dbussink' style='text-decoration:underline;'&gt;Dirkjan Bussink&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;</content>
  </entry>
  
  <entry>
    <title>DataMapper 0.10 is Released</title>
    <link href="http://datamapper.org/articles/datamapper_010_released.html"/>
    <updated>2009-09-15T00:00:00-07:00</updated>
    <id>tag:datamapper.org,2009-09-15</id>
    <content type="html">&lt;h1 id='datamapper_010_is_released'&gt;DataMapper 0.10 is Released&lt;/h1&gt;

&lt;p&gt;DataMapper 0.10 is ready for release. We&amp;#8217;ve worked on it for the past 11 months, pushed 1250 commits, written 3000+ specs, and fixed 140 tickets in the process.&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>DataMapper Presented at RailsConf 2008</title>
    <link href="http://datamapper.org/articles/datamapper_presented_at_railsconf08.html"/>
    <updated>2008-06-10T00:00:00-07:00</updated>
    <id>tag:datamapper.org,2008-06-10</id>
    <content type="html">&lt;h1 id='datamapper_presented_at_railsconf_2008'&gt;DataMapper Presented at RailsConf 2008&lt;/h1&gt;

&lt;p&gt;Yehuda Katz (wycats) gave an updated version of his &amp;#8220;DataMapper - The Persistence Framework&amp;#8221; presentation at Rails Conf 2008. Though video isn&amp;#8217;t available for the talk, he was nice enough to share his slides.&lt;/p&gt;
&lt;div id='__ss_445593' style='width:425px;text-align:left; margin:0 auto;'&gt;&lt;object height='355' style='margin:0px' width='425'&gt;&lt;param name='movie' value='http://static.slideshare.net/swf/ssplayer2.swf?doc=datamapper-1212540345128334-9' /&gt;&lt;param name='allowFullScreen' value='true' /&gt;&lt;param name='allowScriptAccess' value='always' /&gt;&lt;embed src='http://static.slideshare.net/swf/ssplayer2.swf?doc=datamapper-1212540345128334-9' allowfullscreen='true' type='application/x-shockwave-flash' allowscriptaccess='always' height='355' width='425' /&gt;&lt;/object&gt;&lt;div style='font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;'&gt;&lt;a href='http://www.slideshare.net/?src=embed'&gt;&lt;img src='http://static.slideshare.net/swf/logo_embd.png' alt='SlideShare' style='border:0px none;margin-bottom:-5px' /&gt;&lt;/a&gt; | &lt;a href='http://www.slideshare.net/wycats/datamapper?src=embed' title='View DataMapper on SlideShare'&gt;View&lt;/a&gt; | &lt;a href='http://www.slideshare.net/upload?src=embed'&gt;Upload your own&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;They&amp;#8217;re available for download and review direct from SlideShare at &lt;a href='http://www.slideshare.net/wycats/datamapper/'&gt;http://www.slideshare.net/wycats/datamapper/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Adam French (afrench) was in attendance and participated in the &amp;#8216;Birds Of A Feather&amp;#8217; discussion panel on &lt;a href='http://en.oreilly.com/rails2008/public/schedule/detail/4426'&gt;Rails Alternatives and You&lt;/a&gt; led by Mark Bates, of &lt;a href='http://www.mackframework.com/'&gt;www.mackframework.com&lt;/a&gt; fame.&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>DataMapper 0.9 is Released</title>
    <link href="http://datamapper.org/articles/datamapper_090_released.html"/>
    <updated>2008-05-27T00:00:00-07:00</updated>
    <id>tag:datamapper.org,2008-05-27</id>
    <content type="html">&lt;h1 id='datamapper_09_is_released'&gt;DataMapper 0.9 is Released&lt;/h1&gt;

&lt;p&gt;DataMapper 0.9 is ready for the world. It brings with it a massive overhaul of the internals of DataMapper, a shift in terminology, a dramatic bump in speed, improved code-base organization, and support for more than just database data-stores.&lt;/p&gt;

&lt;p&gt;To install it:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;sudo gem install addressable english rspec
sudo gem install data_objects do_mysql do_postgres do_sqlite3
sudo gem install dm-core dm-more
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This is NOT a backwards compatible release. Code written for DataMapper 0.3 will not function with DataMapper 0.9.* due to syntactical changes and library improvements.&lt;/p&gt;

&lt;p&gt;REPEAT: This is NOT a backwards compatible release.&lt;/p&gt;
&lt;table class='changeSummary' cellspacing='0' cellpadding='0'&gt;
  &lt;thead&gt;
    &lt;th&gt;&amp;nbsp;&lt;/th&gt;
    &lt;th&gt;DataMapper 0.3&lt;/th&gt;
    &lt;th&gt;DataMapper 0.9&lt;/th&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;th&gt;Creating a class&lt;/th&gt;
      &lt;td&gt;

&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Post&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;DataMapper&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Base&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

      &lt;/td&gt;
      &lt;td&gt;

&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Post&lt;/span&gt;
  &lt;span class='kp'&gt;include&lt;/span&gt; &lt;span class='no'&gt;DataMapper&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Resource&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Keys&lt;/th&gt;
      &lt;td&gt;

&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='c1'&gt;# Key was not mandatory&lt;/span&gt;
&lt;span class='c1'&gt;# Automatically added +id+ if missing&lt;/span&gt;
&lt;span class='c1'&gt;#&lt;/span&gt;
&lt;span class='c1'&gt;# Natural Key&lt;/span&gt;
&lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:name&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:string&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:key&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
&lt;span class='c1'&gt;#&lt;/span&gt;
&lt;span class='c1'&gt;# Composite Key&lt;/span&gt;
&lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:id&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:integer&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='ss'&gt;:key&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
&lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:slug&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:string&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:key&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

      &lt;/td&gt;
      &lt;td&gt;

&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='c1'&gt;# keys are now mandatory&lt;/span&gt;
&lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:id&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;   &lt;span class='no'&gt;Serial&lt;/span&gt;
&lt;span class='c1'&gt;#&lt;/span&gt;
&lt;span class='c1'&gt;# Natural Key&lt;/span&gt;
&lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:slug&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nb'&gt;String&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='ss'&gt;:key&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
&lt;span class='c1'&gt;#&lt;/span&gt;
&lt;span class='c1'&gt;# Composite Key&lt;/span&gt;
&lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:id&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;   &lt;span class='nb'&gt;Integer&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:key&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
&lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:slug&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nb'&gt;String&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='ss'&gt;:key&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Properties&lt;/th&gt;
      &lt;td&gt;

&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:title&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;     &lt;span class='ss'&gt;:string&lt;/span&gt;
&lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:body&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;      &lt;span class='ss'&gt;:text&lt;/span&gt;
&lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:posted_on&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:datetime&lt;/span&gt;
&lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:active&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;    &lt;span class='ss'&gt;:boolean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

      &lt;/td&gt;
      &lt;td&gt;

&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:title&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;     &lt;span class='nb'&gt;String&lt;/span&gt;
&lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:body&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;      &lt;span class='no'&gt;Text&lt;/span&gt;
&lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:posted_on&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='no'&gt;DateTime&lt;/span&gt;
&lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:active&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;    &lt;span class='no'&gt;Boolean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Associations&lt;/th&gt;
      &lt;td&gt;

&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;has_many&lt;/span&gt; &lt;span class='ss'&gt;:comments&lt;/span&gt;
&lt;span class='n'&gt;belongs_to&lt;/span&gt; &lt;span class='ss'&gt;:blog&lt;/span&gt;
&lt;span class='n'&gt;has_and_belongs_to_many&lt;/span&gt; &lt;span class='ss'&gt;:categories&lt;/span&gt;
&lt;span class='n'&gt;has_one&lt;/span&gt; &lt;span class='ss'&gt;:author&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

      &lt;/td&gt;
      &lt;td&gt;

&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;has&lt;/span&gt; &lt;span class='n'&gt;n&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:comments&lt;/span&gt;
&lt;span class='n'&gt;belongs_to&lt;/span&gt; &lt;span class='ss'&gt;:blog&lt;/span&gt;
&lt;span class='n'&gt;has&lt;/span&gt; &lt;span class='n'&gt;n&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:categories&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='no'&gt;Resource&lt;/span&gt;
&lt;span class='n'&gt;has&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:author&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Finders&lt;/th&gt;
      &lt;td&gt;
        
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='no'&gt;Post&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;first&lt;/span&gt; &lt;span class='ss'&gt;:order&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;created_at DESC&amp;#39;&lt;/span&gt;
&lt;span class='no'&gt;Post&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;all&lt;/span&gt;
  &lt;span class='ss'&gt;:conditions&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;active = ?&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt; &lt;span class='o'&gt;]&lt;/span&gt;

&lt;span class='n'&gt;database&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;query&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;SELECT 1&amp;#39;&lt;/span&gt;
&lt;span class='n'&gt;database&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;execute&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;UPDATE posts...&amp;#39;&lt;/span&gt;
        
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

      &lt;/td&gt;
      &lt;td&gt;
        
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='no'&gt;Post&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;first&lt;/span&gt; &lt;span class='ss'&gt;:order&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt; &lt;span class='ss'&gt;:created_at&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;desc&lt;/span&gt; &lt;span class='o'&gt;]&lt;/span&gt;
&lt;span class='no'&gt;Post&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;all&lt;/span&gt;
  &lt;span class='ss'&gt;:conditions&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;active = ?&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt; &lt;span class='o'&gt;]&lt;/span&gt;

&lt;span class='n'&gt;repository&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:default&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;adapter&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;query&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;SELECT 1&amp;#39;&lt;/span&gt;
&lt;span class='n'&gt;repository&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:default&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;adapter&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;execute&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;UPDATE posts...&amp;#39;&lt;/span&gt;
        
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Validations&lt;/th&gt;
      &lt;td&gt;
        
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;validates_presence_of&lt;/span&gt;     &lt;span class='ss'&gt;:title&lt;/span&gt;
&lt;span class='n'&gt;validates_numericality_of&lt;/span&gt; &lt;span class='ss'&gt;:rating&lt;/span&gt;
&lt;span class='n'&gt;validates_format_of&lt;/span&gt;       &lt;span class='ss'&gt;:email&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;   &lt;span class='ss'&gt;:with&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='ss'&gt;:email_address&lt;/span&gt;
&lt;span class='n'&gt;validates_length_of&lt;/span&gt;       &lt;span class='ss'&gt;:summary&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:within&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='mi'&gt;100&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='n'&gt;validates_uniqueness_of&lt;/span&gt;   &lt;span class='ss'&gt;:slug&lt;/span&gt;
        
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

      &lt;/td&gt;
      &lt;td&gt;
        
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;validates_present&lt;/span&gt;   &lt;span class='ss'&gt;:title&lt;/span&gt;
&lt;span class='n'&gt;validates_is_number&lt;/span&gt; &lt;span class='ss'&gt;:rating&lt;/span&gt;
&lt;span class='n'&gt;validates_format&lt;/span&gt;    &lt;span class='ss'&gt;:email&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;   &lt;span class='ss'&gt;:as&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='ss'&gt;:email_address&lt;/span&gt;
&lt;span class='n'&gt;validates_length&lt;/span&gt;    &lt;span class='ss'&gt;:summary&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:in&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='mi'&gt;100&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='n'&gt;validates_is_unique&lt;/span&gt; &lt;span class='ss'&gt;:slug&lt;/span&gt;
        
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;th&gt;Callbacks&lt;/th&gt;
      &lt;td&gt;

&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;before_save&lt;/span&gt; &lt;span class='ss'&gt;:categorize&lt;/span&gt;

&lt;span class='n'&gt;before_create&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;post&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
  &lt;span class='c1'&gt;# do stuff with post&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='c1'&gt;# return false to abort&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

      &lt;/td&gt;
      &lt;td&gt;

&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;before&lt;/span&gt; &lt;span class='ss'&gt;:save&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:categorize&lt;/span&gt;

&lt;span class='n'&gt;before&lt;/span&gt; &lt;span class='ss'&gt;:create&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
  &lt;span class='c1'&gt;# do stuff with self&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;

&lt;span class='c1'&gt;# throw :halt to abort&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

      &lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;</content>
  </entry>
  
  <entry>
    <title>Living On The Edge Of DataMapper</title>
    <link href="http://datamapper.org/articles/stunningly_easy_way_to_live_on_the_edge.html"/>
    <updated>2008-05-07T00:00:00-07:00</updated>
    <id>tag:datamapper.org,2008-05-07</id>
    <content type="html">&lt;h1 id='living_on_the_edge_of_datamapper'&gt;Living On The Edge Of DataMapper&lt;/h1&gt;

&lt;p&gt;DataMapper is organized into multiple gems that reside within 3 &lt;code&gt;git&lt;/code&gt; repositories. At the very least you will need to clone the &lt;a href='http://github.com/datamapper/extlib'&gt;extlib&lt;/a&gt; and &lt;a href='http://github.com/datamapper/dm-core'&gt;dm-core&lt;/a&gt; gems. If you plan to develop with a relational database, you will also need to install &lt;a href='http://github.com/datamapper/do'&gt;do&lt;/a&gt;. The &lt;a href='http://github.com/datamapper/dm-more'&gt;dm-more&lt;/a&gt; project contains further optional gems that will make developing applications with DataMapper even easier.&lt;/p&gt;

&lt;h3 id='step_0__prerequisites'&gt;Step 0 - Prerequisites&lt;/h3&gt;

&lt;p&gt;First, a couple of basic requirements before we begin. You will need to have an up-to-date installation of &lt;a href='http://www.rubygems.org/'&gt;rubygems&lt;/a&gt;, the &lt;a href='http://www.ruby-lang.org/'&gt;ruby&lt;/a&gt; package management system. To check what version you have, issue the following command:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;gem --version
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If that doesn&amp;#8217;t give at least version 1.3.5, update your &lt;a href='http://www.rubygems.org/'&gt;rubygems&lt;/a&gt; installation by running:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;sudo gem update --system
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Next, you&amp;#8217;ll need &lt;code&gt;git&lt;/code&gt;. It&amp;#8217;s the source code management tool DataMapper uses. Its installation is left up to the reader, but here&amp;#8217;s a few good resources to go to for help:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://git-scm.com/'&gt;Git - Fast Version Control System&lt;/a&gt; - Homepage&lt;/li&gt;

&lt;li&gt;&lt;a href='http://dysinger.net/2007/12/30/installing-git-on-mac-os-x-105-leopard/'&gt;Installing GIT on MAC OSX 10.5 Leopard&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://ropiku.wordpress.com/2007/12/28/git-on-windows/'&gt;Git On Windows&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://chrisolsen.org/2008/03/10/installing-git-on-ubuntu/'&gt;Installing Git on Ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='step_1__gem_dependencies'&gt;Step 1 - Gem dependencies&lt;/h3&gt;

&lt;p&gt;Once you have &lt;code&gt;rubygems&lt;/code&gt; and &lt;code&gt;git&lt;/code&gt; installed, you&amp;#8217;ll need a few gems that &lt;code&gt;datamapper&lt;/code&gt; depends on. To install them, run the following commands. Note that depending on your setup, you will possibly have to prepend &lt;code&gt;sudo&lt;/code&gt; to some of the following commands (this applies to all the commands in this article).&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;gem install gemcutter
gem tumble
gem install rake rspec jeweler addressable
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id='step_2__install_dmcore'&gt;Step 2 - Install dm-core&lt;/h3&gt;

&lt;p&gt;Now that you have everything you need in place, it&amp;#8217;s time to install the &lt;a href='http://github.com/datamapper/extlib'&gt;extlib&lt;/a&gt; and &lt;a href='http://github.com/datamapper/dm-core'&gt;dm-core&lt;/a&gt; gems. To do that, prepare a directory where you will keep the sources, clone the &lt;code&gt;git&lt;/code&gt; repositories, and install the contained gems with the provided &lt;code&gt;rake&lt;/code&gt; tasks.&lt;/p&gt;

&lt;p&gt;Prepare a directory where you will keep the &lt;code&gt;git&lt;/code&gt; clones&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;mkdir -p ~/src/github/vendor
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Change into that directory, clone the repositories and install the gems with the provided rake task.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nb'&gt;cd&lt;/span&gt; ~/src/github/vendor
git clone git://github.com/datamapper/extlib.git
git clone git://github.com/datamapper/dm-core.git
&lt;span class='nb'&gt;cd &lt;/span&gt;extlib/
rake install
&lt;span class='nb'&gt;cd&lt;/span&gt; ..
&lt;span class='nb'&gt;cd &lt;/span&gt;dm-core/
rake install
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id='step_3__install_do_and_dmmore_optional'&gt;Step 3 - Install do and dm-more (Optional)&lt;/h3&gt;

&lt;p&gt;With &lt;a href='http://github.com/datamapper/dm-core'&gt;dm-core&lt;/a&gt; properly installed, you&amp;#8217;re ready to install &lt;a href='http://github.com/datamapper/do'&gt;do&lt;/a&gt; and &lt;a href='http://github.com/datamapper/dm-more'&gt;dm-more&lt;/a&gt;. The &lt;code&gt;do&lt;/code&gt; project provides support for various relational databases and &lt;code&gt;dm-more&lt;/code&gt; contains various gems that help you with common tasks you will face when developing database backed applications.&lt;/p&gt;

&lt;p&gt;Installing a &lt;code&gt;do&lt;/code&gt; adapter requires you to install &lt;code&gt;data_objects&lt;/code&gt; as a minimum requirement. Additionally, you will need to install one or more specific database adapters that are provided within the project. The following shows you how to install &lt;code&gt;data_objects&lt;/code&gt; and the &lt;code&gt;do_mysql&lt;/code&gt; adapter. Replace &lt;code&gt;do_mysql&lt;/code&gt; with whatever provided database adapter you need to work with.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nb'&gt;cd&lt;/span&gt; ~/src/github/vendor
git clone git://github.com/datamapper/do.git
&lt;span class='nb'&gt;cd &lt;/span&gt;&lt;span class='k'&gt;do&lt;/span&gt;/data_objects
rake install
&lt;span class='nb'&gt;cd&lt;/span&gt; ..
&lt;span class='nb'&gt;cd &lt;/span&gt;do_mysql
rake install
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;a href='http://github.com/datamapper/dm-more'&gt;dm-more&lt;/a&gt; project provides various gems that help you with common database development tasks. Clone the &lt;code&gt;git&lt;/code&gt; repository, &lt;code&gt;cd&lt;/code&gt; into the subdirectories that contain the gems you want to use, and &lt;code&gt;rake install&lt;/code&gt; them from there. There is also a &lt;code&gt;rake install&lt;/code&gt; task at the &lt;code&gt;dm-more&lt;/code&gt; root directory which installs all of &lt;code&gt;dm-more&amp;#39;s&lt;/code&gt; gems. Unless you help with developing &lt;code&gt;dm-more&lt;/code&gt; itself, you probably shouldn&amp;#8217;t need to install all the gems that &lt;code&gt;dm-more&lt;/code&gt; provides. The following instructions show how to clone the &lt;code&gt;dm-more&lt;/code&gt; project and install the &lt;code&gt;dm-validations&lt;/code&gt; gem.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nb'&gt;cd&lt;/span&gt; ~/src/github/vendor
git clone git://github.com/datamapper/dm-more.git
&lt;span class='nb'&gt;cd &lt;/span&gt;dm-more/dm-validations
rake install
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id='keeping_up_with_changes'&gt;Keeping up with changes&lt;/h3&gt;

&lt;p&gt;Changes happen to DataMapper and it&amp;#8217;s buddies all the time. To refresh your installation issue the following commands:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nb'&gt;cd&lt;/span&gt; ~/src/github/vendor
&lt;span class='nb'&gt;cd &lt;/span&gt;extlib
git pull origin master
rake install
&lt;span class='nb'&gt;cd&lt;/span&gt; ../dm-core
git pull origin master
rake install
&lt;span class='nb'&gt;cd&lt;/span&gt; ../do
git pull origin master
&lt;span class='nb'&gt;cd &lt;/span&gt;data_objects
rake install
&lt;span class='c'&gt;# cd into the desired adapter subdirectory and rake install from there&lt;/span&gt;
&lt;span class='nb'&gt;cd&lt;/span&gt; ../dm-more
git pull origin master
&lt;span class='c'&gt;# cd into the desired gem subdirectory and rake install from there&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id='uninstall_dmcore_and_friends'&gt;Uninstall dm-core and friends&lt;/h3&gt;

&lt;p&gt;Should you ever have the need to uninstall datamapper completely, Dan Kubb has prepared a bash command that does the trick. Have a look at &lt;a href='http://gist.github.com/31187'&gt;this gist&lt;/a&gt; for a oneliner that gets rid of datamapper completely.&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>DataMapper Presented at MWRC 2008</title>
    <link href="http://datamapper.org/articles/datamapper_talk_atmwrc08.html"/>
    <updated>2008-04-10T00:00:00-07:00</updated>
    <id>tag:datamapper.org,2008-04-10</id>
    <content type="html">&lt;h1 id='datamapper_presented_at_mwrc_2008'&gt;DataMapper Presented at MWRC 2008&lt;/h1&gt;
&lt;a href='http://mwrc2008.confreaks.com/04katz.html' style='border:10px; color:#FFF; text-decoration:none;'&gt;
&lt;img title='Yehuda Katz&amp;apos; presentation entitled &amp;apos;Faster, Better ORM With DataMapper' src='/images/wykatz_at_mwrc2008.png' /&gt;&lt;/a&gt;
&lt;p&gt;At this year&amp;#8217;s &lt;a href='http://mtnwestrubyconf.org/'&gt;Mountain West Ruby Conference 2008&lt;/a&gt;, DataMapper&amp;#8217;s own Yehuda Katz gave a presentation entitled &amp;#8220;Faster, Better ORM With DataMapper.&amp;#8221;&lt;/p&gt;

&lt;p&gt;The video of the talk is available for viewing and downloading at &lt;a href='http://mwrc2008.confreaks.com/04katz.html'&gt;http://mwrc2008.confreaks.com/04katz.html&lt;/a&gt; and is brought to you by the good people at &lt;a href='http://confreaks.com/'&gt;confreaks.com&lt;/a&gt;.&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>Spotlight on... Laziness</title>
    <link href="http://datamapper.org/articles/spotlight_on_laziness.html"/>
    <updated>2008-04-03T00:00:00-07:00</updated>
    <id>tag:datamapper.org,2008-04-03</id>
    <content type="html">&lt;h1 id='spotlight_on_laziness'&gt;Spotlight on&amp;#8230; Laziness&lt;/h1&gt;

&lt;p&gt;Laziness. It means &amp;#8220;an unwillingness to work or use energy&amp;#8221; and typically indicates that the dishes don&amp;#8217;t get washed after lunch, the bath tub doesn&amp;#8217;t get cleaned, and the trash sits around an extra few days and stinks up the place.&lt;/p&gt;

&lt;p&gt;But that very same definition in software takes on a whole new meaning: To avoid doing work you don&amp;#8217;t have to do for as long as you can avoid it; sometimes never doing it at all. It&amp;#8217;s a good thing. It means that expensive and slow tasks can be put off until the very last cycle possible and thus only incur their cost when it really is worth it. Maybe you never execute the code at all.&lt;/p&gt;

&lt;p&gt;You could put off running a specific subroutine because it&amp;#8217;s slow, or because it locks a file that might be needed elsewhere, or because instantiating the resulting object eats up RAM. Either way, deferring execution of a block of code until the very last possible moment can be the difference between a snappy application that rarely slows down and a slow application that rarely speeds up.&lt;/p&gt;

&lt;p&gt;But laziness isn&amp;#8217;t without its hidden costs. If you put off everything to the very last moment, you forfeit the opportunity to do more than one thing at a time, and likely create more work for yourself, rather than less.&lt;/p&gt;

&lt;p&gt;So where&amp;#8217;s the balance?&lt;/p&gt;

&lt;p&gt;Ultimately, it depends on your application. The tools you use should offer you the flexibility you need to design your application optimally. Every system, after all, is unique and breaks the mold of systems before it.&lt;/p&gt;

&lt;p&gt;This brings us to DataMapper.&lt;/p&gt;

&lt;h2 id='lazyloading_attributes'&gt;Lazy-loading attributes&lt;/h2&gt;

&lt;p&gt;You likely already know that DataMapper supports lazy properties.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='lineno'&gt;1&lt;/span&gt; &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Post&lt;/span&gt;
&lt;span class='lineno'&gt;2&lt;/span&gt;   &lt;span class='kp'&gt;include&lt;/span&gt; &lt;span class='no'&gt;DataMapper&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Resource&lt;/span&gt;
&lt;span class='lineno'&gt;3&lt;/span&gt; 
&lt;span class='lineno'&gt;4&lt;/span&gt;   &lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:id&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;    &lt;span class='no'&gt;Serial&lt;/span&gt;                  &lt;span class='c1'&gt;# auto_incrementing primary key&lt;/span&gt;
&lt;span class='lineno'&gt;5&lt;/span&gt;   &lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:title&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nb'&gt;String&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:lazy&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;   &lt;span class='c1'&gt;# intentionally lazy&lt;/span&gt;
&lt;span class='lineno'&gt;6&lt;/span&gt;   &lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:body&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='no'&gt;Text&lt;/span&gt;                    &lt;span class='c1'&gt;# lazy by default&lt;/span&gt;
&lt;span class='lineno'&gt;7&lt;/span&gt; &lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In this case, we&amp;#8217;re intentionally marking this Post&amp;#8217;s &lt;code&gt;:title&lt;/code&gt; property as lazy, as well as letting the &lt;code&gt;:body&lt;/code&gt; be lazy by default. If we go and inspect our query log for the retrieval of a post with the ID of 1, we see&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sql'&gt;&lt;span class='k'&gt;SELECT&lt;/span&gt; &lt;span class='o'&gt;`&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='o'&gt;`&lt;/span&gt; &lt;span class='k'&gt;FROM&lt;/span&gt; &lt;span class='o'&gt;`&lt;/span&gt;&lt;span class='n'&gt;posts&lt;/span&gt;&lt;span class='o'&gt;`&lt;/span&gt; &lt;span class='k'&gt;WHERE&lt;/span&gt; &lt;span class='o'&gt;`&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='o'&gt;`&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;DataMapper didn&amp;#8217;t request the two lazy columns. But when we call &lt;code&gt;.title&lt;/code&gt; off of our post, we suddenly see&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sql'&gt;&lt;span class='k'&gt;SELECT&lt;/span&gt; &lt;span class='o'&gt;`&lt;/span&gt;&lt;span class='n'&gt;title&lt;/span&gt;&lt;span class='o'&gt;`&lt;/span&gt; &lt;span class='k'&gt;FROM&lt;/span&gt; &lt;span class='o'&gt;`&lt;/span&gt;&lt;span class='n'&gt;posts&lt;/span&gt;&lt;span class='o'&gt;`&lt;/span&gt; &lt;span class='k'&gt;WHERE&lt;/span&gt; &lt;span class='o'&gt;`&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='o'&gt;`&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This is the very definition of a lazy-loaded property; The lazy column didn&amp;#8217;t get requested from our data store until we actually needed it, and no sooner.&lt;/p&gt;

&lt;p&gt;But this is just for one individual instance of a post. How does this behave when we have a collection of posts and iteratively call the &lt;code&gt;.title&lt;/code&gt; method?&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sql'&gt;&lt;span class='k'&gt;SELECT&lt;/span&gt; &lt;span class='o'&gt;`&lt;/span&gt;&lt;span class='n'&gt;title&lt;/span&gt;&lt;span class='o'&gt;`&lt;/span&gt; &lt;span class='k'&gt;FROM&lt;/span&gt; &lt;span class='o'&gt;`&lt;/span&gt;&lt;span class='n'&gt;posts&lt;/span&gt;&lt;span class='o'&gt;`&lt;/span&gt; &lt;span class='k'&gt;WHERE&lt;/span&gt; &lt;span class='o'&gt;`&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='o'&gt;`&lt;/span&gt; &lt;span class='k'&gt;IN&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;DataMapper loaded up the title for all of the posts in our collection in one query. It didn&amp;#8217;t issue the lazy-load retrieval from above over and over for each individual post, nor did it chicken out and issue the lazy-load retrieval for ALL of the posts in the data store.&lt;/p&gt;

&lt;p&gt;When you retrieve a set of results using DataMapper&amp;#8217;s &lt;code&gt;.all&lt;/code&gt;, each instance it returns knows about the others in the result set, which makes it brutally simple to issue just one lazy-load retrieval of &lt;code&gt;:title&lt;/code&gt;, and thus solving the n+1 query problem without having to do anything special in the initial retrieval.&lt;/p&gt;

&lt;h2 id='contextual_lazyloading'&gt;Contextual Lazy-loading&lt;/h2&gt;

&lt;p&gt;With a recent commit by &lt;a href='http://www.guyvdb.info/ruby/lazy-loading-properties-in-datamapper/'&gt;Guy van den Berg&lt;/a&gt;, DataMapper just got a whole lot more flexible.&lt;/p&gt;

&lt;p&gt;Most applications have only a few main views of a resource: a brief summary view used in listing results, a complete representation that might appear on a show page and a comprehensive view for when someone is editing something and needs access to metadata. Wouldn&amp;#8217;t it be nice to lump all of the lazy-load retrieval queries into one query which loads up multiple lazy properties, rather than query after query for each lazy property as you call them?&lt;/p&gt;

&lt;p&gt;DataMapper now does this!&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='lineno'&gt;1&lt;/span&gt; &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Post&lt;/span&gt;
&lt;span class='lineno'&gt;2&lt;/span&gt;   &lt;span class='kp'&gt;include&lt;/span&gt; &lt;span class='no'&gt;DataMapper&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Resource&lt;/span&gt;
&lt;span class='lineno'&gt;3&lt;/span&gt; 
&lt;span class='lineno'&gt;4&lt;/span&gt;   &lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:id&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;    &lt;span class='no'&gt;Serial&lt;/span&gt;
&lt;span class='lineno'&gt;5&lt;/span&gt;   &lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:title&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nb'&gt;String&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:lazy&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt; &lt;span class='ss'&gt;:summary&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:brief&lt;/span&gt; &lt;span class='o'&gt;]&lt;/span&gt;
&lt;span class='lineno'&gt;6&lt;/span&gt;   &lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:body&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='no'&gt;Text&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;   &lt;span class='ss'&gt;:lazy&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt; &lt;span class='ss'&gt;:summary&lt;/span&gt; &lt;span class='o'&gt;]&lt;/span&gt;
&lt;span class='lineno'&gt;7&lt;/span&gt; &lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;So now, when you load an attribute with the &lt;code&gt;:summary&lt;/code&gt; context, DataMapper will load up all of the other lazy-loaded properties marked &lt;code&gt;:summary&lt;/code&gt; in one query to the data store.&lt;/p&gt;

&lt;p&gt;In your query log, you&amp;#8217;ll see:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sql'&gt;&lt;span class='lineno'&gt;1&lt;/span&gt; &lt;span class='c1'&gt;-- initial load&lt;/span&gt;
&lt;span class='lineno'&gt;2&lt;/span&gt; &lt;span class='k'&gt;SELECT&lt;/span&gt; &lt;span class='o'&gt;`&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='o'&gt;`&lt;/span&gt; &lt;span class='k'&gt;FROM&lt;/span&gt; &lt;span class='o'&gt;`&lt;/span&gt;&lt;span class='n'&gt;posts&lt;/span&gt;&lt;span class='o'&gt;`&lt;/span&gt;
&lt;span class='lineno'&gt;3&lt;/span&gt; 
&lt;span class='lineno'&gt;4&lt;/span&gt; &lt;span class='c1'&gt;-- lazy-loading of multiple properties in a given context in one query&lt;/span&gt;
&lt;span class='lineno'&gt;5&lt;/span&gt; &lt;span class='k'&gt;SELECT&lt;/span&gt; &lt;span class='o'&gt;`&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='o'&gt;`&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;`&lt;/span&gt;&lt;span class='n'&gt;title&lt;/span&gt;&lt;span class='o'&gt;`&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;`&lt;/span&gt;&lt;span class='n'&gt;body&lt;/span&gt;&lt;span class='o'&gt;`&lt;/span&gt; &lt;span class='k'&gt;FROM&lt;/span&gt; &lt;span class='o'&gt;`&lt;/span&gt;&lt;span class='n'&gt;posts&lt;/span&gt;&lt;span class='o'&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If you use this wisely, it would mean that DataMapper will never load more than it needs nor will it ever fire off more than the absolutely necessary amount of queries to get the job done.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s lazy ;-)&lt;/p&gt;

&lt;h2 id='strategic_eager_loading'&gt;Strategic Eager Loading&lt;/h2&gt;

&lt;p&gt;Well, not for everything.&lt;/p&gt;

&lt;p&gt;Returning for a little bit to our &amp;#8220;loaded set&amp;#8221; discussion from above, every item you pull out of the data store is aware of any other item that got pulled along with it. This is a very powerful feature which lets DataMapper defeat n+1 query problems when dealing with associations as well as lazy-loading of properties.&lt;/p&gt;

&lt;p&gt;For example, this is a severe &amp;#8220;no no&amp;#8221; in ActiveRecord:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='lineno'&gt;1&lt;/span&gt;   &lt;span class='no'&gt;Zoo&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;find&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:all&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;each&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;zoo&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
&lt;span class='lineno'&gt;2&lt;/span&gt;     &lt;span class='n'&gt;zoo&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;animals&lt;/span&gt;
&lt;span class='lineno'&gt;3&lt;/span&gt;   &lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This is a very bad idea because the ORM must query the &amp;#8220;animals&amp;#8221; table over and over again to load the association for each iteration. It&amp;#8217;s far better to use &lt;code&gt;Zoo.find(:all, :include =&amp;gt; [ :animals ]).each {}&lt;/code&gt; because a JOIN occurs and everything is retrieved in 1 query.&lt;/p&gt;

&lt;p&gt;But the same issue doesn&amp;#8217;t exist in DataMapper. Each instance is aware of the other instances it was retrieved with. The same iterator example from above only fires off 2 queries as you&amp;#8217;re iterating and calling the association inside the &lt;code&gt;each&lt;/code&gt;. If you forget to &lt;code&gt;:include =&amp;gt; [ :association ]&lt;/code&gt; in the initial query, DataMapper only ever fires off one more query to get what it needs.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://www.yehudakatz.com/'&gt;Yehuda Katz&lt;/a&gt; has aptly named this &amp;#8216;Strategic Eager Loading&amp;#8217;.&lt;/p&gt;

&lt;h2 id='getting_around_to_it'&gt;Getting Around to It&lt;/h2&gt;

&lt;p&gt;A conclusion for our talk about laziness will be written whenever I get around to it.&lt;/p&gt;

&lt;p&gt;For now, just remember that DataMapper embraces lazy-loading, yet isn&amp;#8217;t overly zealous when the lazy properties are finally retrieved. It also fills associations strategically, and assumes you&amp;#8217;re going to iterate over the set of results. You don&amp;#8217;t have to catch yourself when you write an iterator because DataMapper loads associations for all of your items in the set, rather than on a one-by-one basis.&lt;/p&gt;

&lt;p&gt;And, most importantly, you can avoid doing work you don&amp;#8217;t have to do for as long as you can avoid it.&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>Spotlight on... Composite Keys</title>
    <link href="http://datamapper.org/articles/spotlight_on_cpk.html"/>
    <updated>2008-03-29T00:00:00-07:00</updated>
    <id>tag:datamapper.org,2008-03-29</id>
    <content type="html">&lt;h1 id='spotlight_on_composite_keys'&gt;Spotlight on&amp;#8230; Composite Keys&lt;/h1&gt;

&lt;p&gt;For those of us who have taken a course on database design in college or university, you may have run across a concept called &amp;#8216;Composite Primary Keys&amp;#8217; (or sometimes &amp;#8216;Compound Keys&amp;#8217; or &amp;#8216;Concatenated Keys&amp;#8217;, and abbreviated &lt;abbr title='Composite Primary Keys'&gt;CPK&lt;/abbr&gt;s). It&amp;#8217;s usually right before you tackle JOINs and right after you fight with the &amp;#8220;surrogate key&amp;#8221; or &amp;#8220;primary key&amp;#8221; concept.&lt;/p&gt;

&lt;p&gt;Boiling &lt;abbr title='Composite Primary Keys'&gt;CPK&lt;/abbr&gt;s down, they&amp;#8217;re just a way of identifying a row by multiple keys rather than one. So instead of an auto_incrementing &amp;#8220;serial&amp;#8221; primary key (as in &lt;code&gt;id&lt;/code&gt;), you&amp;#8217;d have a combination of &lt;code&gt;some_column&lt;/code&gt; and &lt;code&gt;some_other_column&lt;/code&gt; that would uniquely identify a row.&lt;/p&gt;

&lt;p&gt;&lt;abbr title='Composite Primary Keys'&gt;CPK&lt;/abbr&gt;s aren&amp;#8217;t as prevalent in the Rails world as Serial Keys (such as the auto-incrementing &lt;code&gt;:id&lt;/code&gt; column), but if you&amp;#8217;re going to support legacy, integration or reporting databases or just de-normalized schemas for performance reasons, they can be invaluable. So sure, Surrogate Keys are a great convenience, but sometimes they just aren&amp;#8217;t an option.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s briefly take a look at how a few ruby ORMs support Composite Primary Keys and then we&amp;#8217;ll talk about DataMapper&amp;#8217;s support for &lt;abbr title='Composite Primary Keys'&gt;CPK&lt;/abbr&gt;s.&lt;/p&gt;

&lt;h2 id='activerecord'&gt;ActiveRecord&lt;/h2&gt;

&lt;p&gt;In short, ActiveRecord doesn&amp;#8217;t support &lt;abbr title='Composite Primary Keys'&gt;CPK&lt;/abbr&gt;s without the help of an external library. &lt;a href='http://drnicwilliams.com/about/'&gt;Dr. Nic Williams&lt;/a&gt; &lt;a href='http://compositekeys.rubyforge.org/'&gt;Composite Keys&lt;/a&gt; is an effort to overcome this limitation.&lt;/p&gt;

&lt;h2 id='sequel'&gt;Sequel&lt;/h2&gt;

&lt;p&gt;Unlike ActiveRecord, Sequel supports &lt;abbr title='Composite Primary Keys'&gt;CPK&lt;/abbr&gt;s natively:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='lineno'&gt;1&lt;/span&gt; &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Post&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;Sequel&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Model&lt;/span&gt;
&lt;span class='lineno'&gt;2&lt;/span&gt;   &lt;span class='n'&gt;set_primary_key&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt; &lt;span class='ss'&gt;:category&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:title&lt;/span&gt; &lt;span class='o'&gt;]&lt;/span&gt;
&lt;span class='lineno'&gt;3&lt;/span&gt; &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='lineno'&gt;4&lt;/span&gt; 
&lt;span class='lineno'&gt;5&lt;/span&gt; &lt;span class='n'&gt;post&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Post&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;ruby&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;hello world&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='lineno'&gt;6&lt;/span&gt; &lt;span class='n'&gt;post&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;key&lt;/span&gt; &lt;span class='c1'&gt;# =&amp;gt; [ &amp;#39;ruby&amp;#39;, &amp;#39;hello world&amp;#39; ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;p(attribution). example compiled from &lt;a href='http://code.google.com/p/ruby-sequel/wiki/SequelModels'&gt;http://code.google.com/p/ruby-sequel/wiki/SequelModels&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id='datamapper'&gt;DataMapper&lt;/h2&gt;

&lt;p&gt;The latest DataMapper was designed from the ground up to support &lt;abbr title='Composite Primary Keys'&gt;CPK&lt;/abbr&gt;s:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='lineno'&gt; 1&lt;/span&gt; &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Pig&lt;/span&gt;
&lt;span class='lineno'&gt; 2&lt;/span&gt;   &lt;span class='kp'&gt;include&lt;/span&gt; &lt;span class='no'&gt;DataMapper&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Resource&lt;/span&gt;
&lt;span class='lineno'&gt; 3&lt;/span&gt; 
&lt;span class='lineno'&gt; 4&lt;/span&gt;   &lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:id&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;   &lt;span class='nb'&gt;Integer&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:key&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
&lt;span class='lineno'&gt; 5&lt;/span&gt;   &lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:slug&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nb'&gt;String&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='ss'&gt;:key&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
&lt;span class='lineno'&gt; 6&lt;/span&gt;   &lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:name&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nb'&gt;String&lt;/span&gt;
&lt;span class='lineno'&gt; 7&lt;/span&gt; &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='lineno'&gt; 8&lt;/span&gt; 
&lt;span class='lineno'&gt; 9&lt;/span&gt; &lt;span class='n'&gt;pig&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Pig&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Porky&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='lineno'&gt;10&lt;/span&gt; 
&lt;span class='lineno'&gt;11&lt;/span&gt; &lt;span class='n'&gt;pig&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;key&lt;/span&gt; &lt;span class='c1'&gt;# =&amp;gt; [ 1, &amp;#39;Wilbur&amp;#39; ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;We declared our keys by adding the &lt;code&gt;:key =&amp;gt; true&lt;/code&gt; to the appropriate properties. The order is important as it will determine the order keys are addressed throughout the system.&lt;/p&gt;

&lt;p&gt;Next, we mixed and matched the keys&amp;#8217; types. &lt;code&gt;:id&lt;/code&gt; is a Integer, but &lt;code&gt;:slug&lt;/code&gt; is a String. DataMapper didn&amp;#8217;t flinch when we defined a key column as a String because it supports &lt;a href='http://en.wikipedia.org/wiki/Natural_key'&gt;Natural Keys&lt;/a&gt; as well.&lt;/p&gt;

&lt;p&gt;Lastly, when retrieving rows via &lt;code&gt;get&lt;/code&gt; and &lt;code&gt;[]&lt;/code&gt; with a &lt;abbr title='Composite Primary Keys'&gt;CPK&lt;/abbr&gt;, we supplied the keys in the order they were defined within our model. For example, we defined &lt;code&gt;:id&lt;/code&gt; first, then &lt;code&gt;:slug&lt;/code&gt; second; later, we retrieved Porky by specifying his &lt;code&gt;:id&lt;/code&gt; and &lt;code&gt;:slug&lt;/code&gt; in the same order. Additionally, when we asked Wilbur for his keys, he handed us an array in the order the keys were defined.&lt;/p&gt;

&lt;p&gt;We didn&amp;#8217;t need to mix in an external library to get support for &lt;abbr title='Composite Primary Keys'&gt;CPK&lt;/abbr&gt;s, nor did we need to call a &lt;code&gt;set_primary_key&lt;/code&gt; method and then supply more than one key to it. DataMapper supports Composite Primary Keys intuitively and without compromise!&lt;/p&gt;

&lt;p&gt;In later &amp;#8220;Spotlight On&amp;#8230;&amp;#8221; articles, we&amp;#8217;ll examine and demonstrate other DataMapper features or persistence concepts as well as compare similar features with other ORMs or libraries.&lt;/p&gt;</content>
  </entry>
  
  <entry>
    <title>The Great Refactoring</title>
    <link href="http://datamapper.org/articles/the_great_refactoring.html"/>
    <updated>2008-03-22T00:00:00-07:00</updated>
    <id>tag:datamapper.org,2008-03-22</id>
    <content type="html">&lt;h1 id='the_great_refactoring'&gt;The Great Refactoring&lt;/h1&gt;

&lt;p&gt;&amp;#8220;Tip&amp;#8221; DataMapper (hosted on &lt;a href='http://github.com/datamapper/dm-core'&gt;github&lt;/a&gt;) is going through a dramatic re-factor. Here&amp;#8217;s a quick summary of the anticipated NEW public API.&lt;/p&gt;

&lt;h2 id='not_just_for_databases_anymore'&gt;Not Just for Databases Anymore&lt;/h2&gt;

&lt;p&gt;DataMapper&amp;#8217;s class terminology will change and &amp;#8216;de-couple&amp;#8217; itself from database-specific terminology. Gone are &amp;#8220;database&amp;#8221;, &amp;#8220;table&amp;#8221;, &amp;#8220;column&amp;#8221; and &amp;#8220;join&amp;#8221;. Say hello to &amp;#8220;Repository&amp;#8221;, &amp;#8220;Resource&amp;#8221;, &amp;#8220;Property&amp;#8221;, and &amp;#8220;Link&amp;#8221;.&lt;/p&gt;

&lt;p&gt;&amp;#8220;Why would you want to do that?&amp;#8221;, you ask. Ultimately it&amp;#8217;s because DataMapper will soon support different types of persistence layers, not just databases. It&amp;#8217;ll talk to all sorts of things like web services (REST and such), XML files, YAML files, non-relational databases, even custom file-types or services of your own design. Just implement an Adapter that conforms to a certain API and DataMapper could support any type of data store. No need for a completely separate library or anything.&lt;/p&gt;

&lt;p&gt;As an added benefit, DataMapper become more &amp;#8220;RESTful&amp;#8221;. &lt;a href='http://tomayko.com/writings/rest-to-my-wife'&gt;Ryan Tomayko&lt;/a&gt; has a very good explanation of REST that all should read entitled &lt;a href='http://tomayko.com/writings/rest-to-my-wife'&gt;How I Explained REST to My Wife&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id='model_definitions_are_a_little_different'&gt;Model Definitions Are a Little Different&lt;/h2&gt;

&lt;p&gt;Since we&amp;#8217;re changing up the terminology, model definitions are going to change up a little bit. Here&amp;#8217;s what a Planet model would look like using the new API:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='lineno'&gt;1&lt;/span&gt; &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Planet&lt;/span&gt;
&lt;span class='lineno'&gt;2&lt;/span&gt;   &lt;span class='kp'&gt;include&lt;/span&gt; &lt;span class='no'&gt;DataMapper&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Resource&lt;/span&gt;
&lt;span class='lineno'&gt;3&lt;/span&gt; 
&lt;span class='lineno'&gt;4&lt;/span&gt;   &lt;span class='n'&gt;resource_names&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:legacy&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;dying_planets&amp;#39;&lt;/span&gt;
&lt;span class='lineno'&gt;5&lt;/span&gt; 
&lt;span class='lineno'&gt;6&lt;/span&gt;   &lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:name&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nb'&gt;String&lt;/span&gt;
&lt;span class='lineno'&gt;7&lt;/span&gt;   &lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:age&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='nb'&gt;Integer&lt;/span&gt;
&lt;span class='lineno'&gt;8&lt;/span&gt;   &lt;span class='n'&gt;property&lt;/span&gt; &lt;span class='ss'&gt;:core&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nb'&gt;String&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;  &lt;span class='ss'&gt;:private&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;
&lt;span class='lineno'&gt;9&lt;/span&gt; &lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;A couple of things are going on here. First, DataMapper::Base and DataMapper::Persistence are gone and replaced with &lt;a href='http://www.yardoc.org/docs/datamapper-dm-core/DataMapper/Resource'&gt;DataMapper::Resource&lt;/a&gt;. Next &lt;code&gt;set_table_name&lt;/code&gt; has been replaced with &lt;code&gt;resource_names&lt;/code&gt; hash where you specify which arena play occurs in. After that we have a couple of Property definitions that look a little different.&lt;/p&gt;

&lt;p&gt;First off, Properties will no longer take &lt;code&gt;:symbols&lt;/code&gt; for their types and instead take real constants like String, Integer, DateTime. Also on the docket are the ability to define your own custom types.&lt;/p&gt;

&lt;p&gt;Think about that for a minute. If developers are able to define their own custom types with their own materialization and serialization methods, DataMapper will be able to support all kinds of wild data-types like GIS information, network information, marshaled objects, JSON&amp;#8230;pretty much anything a developer might need, or want.&lt;/p&gt;

&lt;h2 id='a_commandline_interface'&gt;A Command-Line Interface&lt;/h2&gt;

&lt;p&gt;Taking a lesson from web frameworks, DataMapper will sport an interactive command-line so that you can browse your resources without the need to load up the entire environment of your application. Here&amp;#8217;s an example session:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='lineno'&gt;1&lt;/span&gt; &lt;span class='nv'&gt;$ &lt;/span&gt;dm mysql://root@localhost/great_musicians &lt;span class='c'&gt;# connecting to a repository&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;An IRB session boots up&amp;#8230;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='o'&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;the_king&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Person&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;first&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:name&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;elvis&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='o'&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;the_king&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;alive?&lt;/span&gt; &lt;span class='c1'&gt;# =&amp;gt; maybe&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This is very similar to &lt;code&gt;script/console&lt;/code&gt; in Rails or &lt;code&gt;merb -i&lt;/code&gt; in Merb, only it won&amp;#8217;t load up the entire environment of your application, just your DataMapper resources and their associations, methods, and such. If you prefer &amp;#8220;fat models&amp;#8221;, this will constitute the core of your application.&lt;/p&gt;

&lt;h2 id='how_this_all_comes_together'&gt;How This All Comes Together&lt;/h2&gt;

&lt;p&gt;This is the coolest new feature of DataMapper: we&amp;#8217;re skipping all the way from 0.3.0 to 0.9! Get excited, contact the press, fire up the blogosphere! Its a huge jump and we&amp;#8217;re honestly concerned that people may not be able to handle it.&lt;/p&gt;

&lt;p&gt;Alright, so it&amp;#8217;s not &lt;em&gt;that&lt;/em&gt; big of a deal, but we&amp;#8217;re confident that all of this will get DataMapper so close to going 1.0 that we&amp;#8217;ll be able to taste it. To get there, DataMapper&amp;#8217;s more advanced features like single table inheritance, paranoia, and chained associations will be re-implemented to use all this new stuff, and then we&amp;#8217;re sure 0.9 will need a touch up or two.&lt;/p&gt;

&lt;p&gt;So close&amp;#8230;.so very very close&amp;#8230;&lt;/p&gt;

&lt;p&gt;Stay tuned in to the &lt;a href='http://groups.google.com/group/datamapper'&gt;mailing list&lt;/a&gt;, check up on the &lt;a href='http://datamapper.org/'&gt;wiki&lt;/a&gt;, chat it up in &lt;a href='irc://irc.freenode.net/#datamapper'&gt;#datamapper&lt;/a&gt; and watch &lt;a href='http://github.com/datamapper/dm-core/commits/master'&gt;github commit messages&lt;/a&gt; for updates.&lt;/p&gt;</content>
  </entry>
  

</feed>
