mongoDBをrubyからmongo使う(mongo-acriverecord-ruby)
mongo-acriverecord-rubyを使うと、mongoDBでactiverecordチックにアクセスできる。
http://github.com/mongodb/mongo-activerecord-ruby:mongo-activerecord-ruby
本当のactiverecordから使うならhttp://github.com/mongodb/activerecord-mongo-adapter:activerecord-mongo-adapterがいいみたいです。
せっかくのドキュメント指向なのにRDB風に使うのはどうなの?とか思いますが。
インストール
前提としてhttp://d.hatena.ne.jp/amacou/20091205/1260035177:昨日の作業はやっていて、デーモンも上がっている状態です。
gemcutterすでにインストールしてるなら以下は省略。
$ sudo gem install gemcutter $ sudo gem tumble
でインストール
$ sudo gem install mongo_record
使ってみる
では、ありがちなblogっぽいDBの操作をやってみます。
まずはPostクラスを作ります。
#post.rb require "mongo" require "mongo_record" require File.join(File.dirname(__FILE__), 'comment') class Post < MongoRecord::Base collection_name :posts fields :title, :content has_many :comments, :class_name => "Comment" def to_s "title: #{self.title} content: #{self.content}" end end
つぎにCommentクラスを作ります。
#comment.rb require "mongo" require "mongo_record" class Comment < MongoRecord::Base collection_name :comments fields :name, :content belongs_to :post def to_s "name: #{self.name}, content: #{self.content}" end end
上記を使うMainファイルを作ります。
#blog.rb # -*- coding: utf-8 -*- require "mongo" require "mongo_record" require File.join(File.dirname(__FILE__), 'post') require File.join(File.dirname(__FILE__), 'comment') MongoRecord::Base.connection = Mongo::Connection.new.db('blog') #とりあえず空にしとく Post.destroy_all Comment.destroy_all def show puts "" puts "=" * 50 Post.find(:all).each do |pos| puts "日記" puts " #{pos}" pos.comments.each do |com| puts " コメント" puts " #{com}" end end puts "=" * 50 puts "" end puts "日記をつける" post = Post.new(:title => "うんこ", :content => "きょうはおおきなうんこがでた" ) post.save show puts "コメントをつける(belogs_to を利用)" comment = Comment.new(:name => "通りすがりさん", :content => "わたしもおおきなうんこでした", :post => post) comment.save show puts "コメントをつける2( << を利用)" comment2 = Comment.create(:name => "通りすがりさん", :content => "わたしはコロコロのうんこでした") post.comments << comment2 post.save show puts "自作自演日記をつける" comment3 = Comment.create(:name => "自作自演さん", :content => "まだだしちゃだめ") post2 = Post.new(:title => "うんこ", :content => "でそう", :date => Date.new, :comments => comment ) post2.save show
で実行
$ ruby blog.rb 日記をつける ================================================== 日記 title: うんこ content: きょうはおおきなうんこがでた ================================================== コメントをつける(belogs_to を利用) ================================================== 日記 title: うんこ content: きょうはおおきなうんこがでた ================================================== コメントをつける2( << を利用) ================================================== 日記 title: うんこ content: きょうはおおきなうんこがでた コメント name: 通りすがりさん, content: わたしはコロコロのうんこでした ================================================== 自作自演日記をつける ================================================== 日記 title: うんこ content: きょうはおおきなうんこがでた コメント name: 通りすがりさん, content: わたしはコロコロのうんこでした 日記 title: うんこ content: でそう コメント name: 通りすがりさん, content: わたしもおおきなうんこでした ==================================================
ソース見てみたら、belongs_toはまだ実装されていないみたいです。
でもhas_manyとか関連はちゃんと動いています。
実データはどうなっているのか確認。
mongoコマンドでインタラクティブにDBを操作できます。
$ mongo MongoDB shell version: 1.1.4 url: test connecting to: test type "help" for help > use blog switched to db blog > show collections comments posts system.indexes > db.posts.find() { "_id" : ObjectId("4b1bcc000b965d203b000001"), "created_at" : "Mon Dec 07 2009 00:21:36 GMT+0900 (JST)", "comments" : [ { "$ref" : "comments", "$id" : ObjectId("4b1bcc000b965d203b000003") } ], "created_on" : "Mon Dec 07 2009 00:00:00 GMT+0900 (JST)", "title" : "うんこ", "updated_at" : "Mon Dec 07 2009 00:21:36 GMT+0900 (JST)", "_ns" : "posts", "updated_on" : "Mon Dec 07 2009 00:00:00 GMT+0900 (JST)", "content" : "きょうはおおきなうんこがでた" } { "_id" : ObjectId("4b1bcc000b965d203b000005"), "created_at" : "Mon Dec 07 2009 00:21:36 GMT+0900 (JST)", "comments" : [ { "$ref" : "comments", "$id" : ObjectId("4b1bcc000b965d203b000002") } ], "created_on" : "Mon Dec 07 2009 00:00:00 GMT+0900 (JST)", "title" : "うんこ", "updated_at" : null, "_ns" : "posts", "updated_on" : null, "date" : /(?:)/, "content" : "でそう" }
commentsの中に配列で関連するcommentのIDを保存している。
ちなみにcommentsは以下のようになってました。
> db.comments.find() { "_id" : ObjectId("4b1bcc000b965d203b000002"), "name" : "通りすがりさん", "created_at" : "Mon Dec 07 2009 00:21:36 GMT+0900 (JST)", "post" : { "$ref" : "posts", "$id" : ObjectId("4b1bcc000b965d203b000001") }, "created_on" : "Mon Dec 07 2009 00:00:00 GMT+0900 (JST)", "_ns" : "comments", "content" : "わたしもおおきなうんこでした" } { "_id" : ObjectId("4b1bcc000b965d203b000003"), "name" : "通りすがりさん", "created_at" : "Mon Dec 07 2009 00:21:36 GMT+0900 (JST)", "created_on" : "Mon Dec 07 2009 00:00:00 GMT+0900 (JST)", "_ns" : "comments", "content" : "わたしはコロコロのうんこでした" } { "_id" : ObjectId("4b1bcc000b965d203b000004"), "name" : "自作自演さん", "created_at" : "Mon Dec 07 2009 00:21:36 GMT+0900 (JST)", "created_on" : "Mon Dec 07 2009 00:00:00 GMT+0900 (JST)", "_ns" : "comments", "content" : "まだだしちゃだめ" }
ドキュメント指向ってちゃんと勉強していないけど、上記のようなデータだと、postもcommentも同じコレクションにしちゃった方がいいのかな?
ちゃんとドキュメント指向を勉強してみたいです。
(参考になるサイトや参考書をご存知のかたは教えてください。)