Tuesday, August 12, 2008

Sample Application Using Edge Merb and DataMapper

Okay, now that you have edge Merb and DataMapper installed, let's create our first app. Pick a directory where you want to put your app, and try the following:

$ merb-gen app sample

You should see "Generating with app generator:" followed by a list of the new directories and files Merb added for you. Change into that directory:

cd sample

and edit the config/init.rb file. Uncomment the DataMapper ORM line:

use_orm :datamapper

and also add a dependencies on merb_helpers and merb-assets:

# ==== Dependencies

# These are some examples of how you might specify dependencies.
# Dependency loading is delayed to a later Merb app
# boot stage, but it may be important when
# another part of your configuration relies on libraries specified
# here.
#
dependencies "merb_helpers", "merb-assets"

Finally, if you want to add query logging from DataMapper, add this to the 'after_app_loads' block:


Merb::BootLoader.after_app_loads do

  DataObjects::Mysql.logger = DataObjects::Logger.new('log/dm.log', 0)

end

Now, let's set up our databases:

$ rake dm:db:database_yaml

Rename (or move) the generated config/database.yml.sample file to config/database.yml. Then go ahead and enter the correct values for the setup you want. Here's how I have mine:



development: &defaults
# These are the settings for repository :default
adapter: mysql
database: sample_development
username: root
password:
host: localhost

test:
<<: *defaults
database: sample_test

production:
<<: *defaults
database: sample_production

Next, let's create a resource:

merb-gen resource Post title:string body:text created_at:date_time

(NOTE: Run merb-gen with no arguments to see a complete list of generators.)

Make sure that you use 'date_time' and not 'datetime' as you would with ActiveRecord. Otherwise, the created_at field will be assigned the type 'Datetime' (which is wrong), and not the correct 'DateTime'. One other potential gotcha - DataMapper strings will generate a varchar(50) field in MySQL, not varchar(255) like in ActiveRecord.

The merb-gen command will generate a Post model at app/models/post.rb, among other files. Take a look at the file now:

class Post
include DataMapper::Resource

property :title, String
property :body, Text
property :created_at, DateTime

end

You will need to add a property (I put it above the other properties):

property :id, Integer, :serial => true

because DataMapper requires you to explicitly declare the primary key. Next, go ahead and run the migration:

rake dm:db:automigrate

Note that the dm:db:automigrate task is destructive. If you create any posts, then run the task again, the table will be dropped and recreated, causing you to lose your data.

You will also need to edit config/router.rb, because Merb doesn't add the Post resource to the routes automatically:


Merb::Router.prepare do |r|
# RESTful routes
r.resources :posts
end

Now let's take a look at the views (the posts controller at app/controllers/posts.rb should have everything you need from the merb-gen resource command). I modified my app/views/posts/new.html.erb file to look like this:

<h1>New Post</h1>
<%= error_messages_for :post %>

<% form_for(:post, :action => url(:posts) do %>
<%= partial('form', :button_text => 'Create') %>
<% end %>

<%= link_to 'Back', url(:posts) %>

I moved the form elements into a form partial at app/views/posts/_form.html.erb:



<p>
<label for="post_title">Title: </label><br/>
<%= text_control :title %>
</p>
<p>
<label for="post_body">Body: </label><br/>
<%= text_area_control :body %>
</p>
<p>
<%= submit_button button_text %>
</p>


You can probably guess what the edit view looks like.

Let's fire up merb and take a look in the browser:

$ merb

(NOTE: enter 'merb --help' to see a complete list of options to the 'merb' command).

Now open up your favorite browser and navigate to 'http://localhost:4000/posts'. You should see something very like this:


Now go ahead and create your first post!

Monday, August 11, 2008

Edge Merb and DataMapper on Leopard

After doing this a few times, I decided I'd document my steps for getting edge Merb with DataMapper up and running on a Leopard box. Be forewarned: when working with edge Merb and DataMapper, be prepared to deal with things breaking, at least until Merb gets to 1.0.

First, install the gems that Merb depends on:

$ sudo gem install english erubis hpricot json_pure mime-types rack

Next, install Git. You can try installing Git from source if you want, but MacPorts worked fine for me.

$ sudo port install git-core

Once you have Git installed, head on over to Github to start cloning the various repositories you'll need. I suggest creating one directory where you keep all your Merb-related repositories - I keep mine in ~/dev/merb.

$ git clone git://github.com/sam/extlib.git
$ git clone git://github.com/wycats/merb-core.git
$ git clone git://github.com/wycats/merb-more.git
$ git clone git://github.com/wycats/merb-plugins.git

These are the four main repositories for Merb. As the names suggest, if you wanted to just do barebones Merb hacking, you could get by with just merb-core and skip merb-more and merb-plugins. But in my experience, you're going to want them eventually, so I advise just installing them now.

Now we'll install each gem:

$ cd extlib
$ sudo rake install
$ cd ../merb-core
$ sudo rake install
$ cd ../merb-more
$ sudo rake install
$ cd ../merb-plugins
$ sudo rake install
$ cd ..

Congratulations, you now have edge Merb installed!

Next, let's install edge DataMapper. First, install the addressable gem, a dependency of data_objects:

sudo gem install addressable

Next, change directories back into your top-level Merb directory, if you haven't already by following the instructions above, and clone the necessary repositories.

$ git clone git://github.com/sam/do.git
$ git clone git://github.com/sam/dm-core.git
$ git clone git://github.com/sam/dm-more.git

Now go ahead and install the DataMapper dependencies and gems (NOTE - I got an error related to the PostgresSQL install here, but I don't use it. It may affect you however.):

$ cd do
$ sudo rake install
$ cd ../dm-core
$ sudo rake install
$ cd ../dm-more
$ sudo rake install
$ cd ..

Excellent, now you're ready to create a Merb app on the edge!