Okay. So day 1. I've chosen to use MongoMapper for now over the other two I've provided last post. MongoMapper is quite good, I haven't read/delved into their code but he said it was readable so looking forward to it. I just hope they don't make MongoMapper too rails-specific.
Okay, so moving on. I've started with the basics of most apps that is "Inserting data" on a "Collection". And having a "One to Many" relationship. This is just a basic app where you could post and comment to demonstrate. I assume here that you already have working applications and just want to start out using MongoDB.
The model would look like this.
Message Model
class Message
include MongoMapper::Document
key :name, String, :require => true
key :body, String, :require => true
timestamps! # This would create a "created_at" and "updated_at" keys on create
many :comments
end
Take note that I have defined keys in the model. The keys can have typecast but it doesn't require you to have one. Also, you need not to define every key in the model as documents are schema-less, that's also one of the reasons of using MongoDB (unkown unknowns).
So for example you have a key :blah.
Test Model
class Test
include MongoMapper::Document
key :blah
end
Test.create :blah => 42
# => { "_id" : ObjectId("..."), "blah" : 42 }
Test.create :blah => "the answer"
# => { "_id" : ObjectId("..."), "blah" : "the answer" }
Test.create :blah => 42, :answer => "ultimate question"
# => { "_id" : ObjectId("..."), "blah" : 42, "answer" => "ultimate question" }
Okay. Going back to inserting records (but I think I've shown that already in the test). I only have basic information for now but here is a snippet of posting.
def post
if request.post?
Message.create :name => request[:name], :body => request[:body]
redirect r(:/)
end
end
Upon posting a message here, the data would look something like this.
{ "_id" : ObjectId("..."), "name" : "Post 2", "created_at" : "Tue Sep 07 2010 18:31:45 GMT 0800 (PHT)", "body" : "Test Body!", "updated_at" : "Tue Sep 07 2010 18:31:45 GMT 0800 (PHT)" }
Now I'd like to step on to relations, embedded documents.
Did you notice the last line before ending the MessageModel? It is a many relationship to comments. A comment model would look like this:
Comment Model
class Comment
include MongoMapper::EmbeddedDocument
key :name, String, :require => true
key :body, String, :require => true
end
Note on the line 2 EmbeddedDocument would embed this document on the Message document. To try it out:
Per post snippet
def posts(id = nil)
id = id || request[:id]
redirect r(:/) unless @msg = Message.find(id)
if request.post?
@msg.comments << Comment.new(:name => request[:name], :body => request[:body])
@msg.save
end
end
This would produce a record like this
{ "_id" : ObjectId("4c8618b6be9294085d000001"), "name" : "Post 3", "created_at" : "Tue Sep 07 2010 18:49:26 GMT 0800 (PHT)", "comments" : [
{
"name" : "Tester",
"body" : "Comment Yah!",
"_id" : ObjectId("4c862781be929409d100000a")
}
], "body" : "Another test body!", "updated_at" : "Tue Sep 07 2010 19:52:33 GMT 0800 (PHT)" }
Then when you pull the data from the "Per post snippet". You could iterate on the comments like so:
<% @msg.comments.each do |c| %>
<%= c.name %><br />
<%= c.body %><br />
<% end %>
This app and idea is far from perfect as it would still require validations and some form of filter to remove scripts but you get the gist of it. Also, I didn't include the views as I haven't written them completely as well, they are just basic forms with inputs and textareas and iterations for display but I think you all get what they would look like. If you need to see it, post a comment and I'll email it to you.
I don't know if I have written it awesome for now but I would like to hear how others are doing with Ramaze with MongoDB and MongoMapper.
Also, here is a complete code of the controller:
class MessagesController < Ramaze::Controller
map '/'
def index
@msgs = Message.all
end
def post
if request.post?
Message.create :name => request[:name], :body => request[:body]
redirect r(:/)
end
end
def posts(id = nil)
id = id || request[:id]
redirect r(:/) unless @msg = Message.find(id)
if request.post?
@msg.comments << Comment.new(:name => request[:name], :body => request[:body])
@msg.save
end
end
end
No comments:
Post a Comment