merb 0.9.5 + haml + datamapper + sqlite3

2008 September 4
by robertor

Since Merb is constantly changing prior to its 1.0 release, a lot of the tutorials did not work exactly the way I expected them to work.

I was looking for a tutorial that covered a simple Merb + HAML + DataMapper + SQLite application. I found that a good candidate to tweak was the simple chat wall tutorial that was prominently linked on the Merb wiki. The following are some code updates to get it working with Merb 0.9.5, HAML, DataMapper, and SQLite. Feedback is welcome.

merb-gen app

merb-gen app allows you to specify the template engine, ORM, and testing framework directly on the command line:

merb-gen app slapp --template-engine haml --orm datamapper --testing-framework rspec

init.rb

DataMapper dependencies should be specified in init.rb to get counts/aggregates, automatic created_at timestamps, and validations. Datamapper can also handle session storage. And don’t forget to set the :session_id_key!

init.rb contents

dependency "dm-aggregates"
dependency "dm-timestamps"
dependency "dm-validations"
dependency "merb_helpers"

...

use_orm :datamapper

...

use_template_engine :haml

...

  c[:session_id_key] = 'chat_wall_session_id'

...

  c[:session_store] = 'datamapper'

...

SQLite database configuration and setup

DataMapper offers a rake task to create a sample database.yml file:
rake dm:db:database_yaml

Here’s what a database.yml file for development and test SQLite databases looks like:

database.yml contents

---
:development: &defaults
  :adapter:  sqlite3
  :database: db/dev.db

:test:
  <<: *defaults
  :database: db/test.db

:production: &defaults
  :adapter:  mysql
  :database: slapp_production
  :username: someuser
  :password: somepassword
  :host:     localhost
  :port:     3306

Creating the SQLite development and test databases:
sqlite db/dev.db
sqlite db/test.db

Database sessions migration:
rake dm:sessions:create

Database migration:
rake dm:db:automigrate

Post model

Model validations didn’t seem to be working properly…

post.rb contents

class Post
  include DataMapper::Resource

  property :id, Serial
  property :body, String
  property :created_at, DateTime

  validates_length :body, :minimum => 2
end

HAML

I had problems with the Merb form helper in the index HAML file…

app/views/posts/index.html.haml contents

!!! Loose
%html{html_attrs{'en-us'}}
  %body
    %h1 Welcome to Slapp
    %h2 A simple chat wall

    %p Recent Posts:
    .container{:id => 'posts'}= partial("shared/post", :with => @posts)

    %div Post Something:
    - #form_for(:post, :action => url(:posts) ) do
    %form{ :action => '/posts/create', :method => :post}
      = text_field(:name => "body", :size => 40)
      = submit "Post Message!"

The individual post HAML file…

app/views/shared/_post.html.haml contents

.post{:id => 'post-' + post.id.to_s}
  .body= h(post.body)
  .created= relative_date(post.created_at)

RSpec

Lastly, I had to change some of the CSS selectors and the deletion method for the index spec…

spec/views/posts/index_spec.rb contents

...

  it "should have a containing div for the posts" do
    @body.should have_selector("div#posts.container")
  end

  it "should have a div for each individual post" do
    @posts.each do |post|
      @body.should have_selector("div#posts.container div#post-#{ post.id }.post")
    end
  end

  it "should have the contents of each post inside a div with an id and class" do
    @posts.each do |post|
      @body.should have_tag("div#posts") do
        with_tag(:div, :id => "post-#{ post.id }", :class => "post", :content => post.body)
      end
    end
  end

  it "should have a form to create new posts with a single input and submit button" do
    @body.should have_selector("form[@action='/posts/create']")
    @body.should have_selector("form[@action='/posts/create'] input[@name='body']")
    @body.should have_selector("form[@action='/posts/create'] input[@type='submit']")
  end

  after(:each) do
    Post.all.destroy!
  end

...
2 Responses leave one →
  1. 2008 October 4
    Vladimir permalink

    I’m also having problems with form_for inside haml – have you managed to resolve the issue? The tag that everyone seems to be using in the RHTML seems to be at the root of the problem…

  2. 2008 October 10

    Not sure if this is your problem, but it took me a while to find this article:

    http://merbunity.com/news/29

    The form helpers that take a block return strings now, so you have to use an ‘=’ instead of a ‘-’, like this:

    = form_for(@post, :action => url(:post, @post)) do

Leave a Reply

Note: You can use basic XHTML in your comments. Your email address will never be published.

Subscribe to this comment feed via RSS