After some initial excitement learning about DataMapper, I became concerned that it might not be all it that I thought it was.
Thankfully, it is!
I was concerned about the associations capability. The documentation sounded great, but got a little fuzzy on me.
I finally figured it out, and here's a quick and simple explanation of what I was concerned about. This should be an interesting example as it also involves single table inheritance:
class Entry include DataMapper::Resource property :id,Serial property :memorandum,String property :status,Integer property :fiscal_period_id,Integer has n, :credits has n, :debits end class Amount include DataMapper::Resource property :id,Serial property :entry_id,Integer property :type,Discriminator property :amount,String property :account_id,Integer property :memorandum,String belongs_to :entry belongs_to :account end class Credit < Amount; end class Debit < Amount; end
Can you guess what type of data model this is? That's right - a double entry accounting system!
Entries and credit and debit amounts are bound by foreign key constraints. Inasmuch, they are often grouped into result sets.
The DataMapper docs clearly explain how to get the entries, like this:
get '/entries' do @myitems = Entry.all() erb :entry_list end
But how can I get the credits and debits as well? It took a minute to figure it out, but I don't have to do anything at all. DataMapper does it for me. Impressive!
To be more specific, I'll include this erb template, which is accesses the @myitems object, and what an object it turns out to be!
<div class="accounts"> <ul> <% @myitems.each do | item | %> <li>Entries: <%= item.id %>,<%= item.memorandum %> <br /><% item.credits.each do | credit | %> Credits: <%= credit.id %>,<%= credit.amount %><br/> <% end %> <br /><% item.debits.each do | debit | %> Debits: <%= debit.id %>,<%= debit.amount %><br/> <% end %> </li> <% end %> </ul> </div>
See what happens? I iterate through the entries, and on each entry, I'm able to access the associated data objects. C'est incroilable!
I'm not too crazy about erb templates, and I think that's one of the reasons why I had such a hard time figuring out the way DataMapper associations work.
Wait! I'm not done yet. Another question I had involved how to create entry rows and associated amount rows.
post '/new/entry' do @entry = Entry.new(:memorandum => params[:entry_name]) @entry.save @credit = @entry.credits.create(:amount => '5.00') @debit = @entry.debits.create(:amount => '2.00') @debit = @entry.debits.create(:amount => '3.00') redirect '/entries' end
There is no error checking going on there, and the entry amounts are hard-coded, but it was enough for me to learn how DataMapper associations assist with the creation of data.
NOTE: This code is from a Sinatra app I'm working on, hence the:
post '/new/entry' do