Ruby on Rails框架程序连接MongoDB的教程
前边有介绍mongodb的安装以及ror项目的搭建,现在进行一下整合。
1.创建项目
创建项目时不再使用railsactive_record支持
railsnewtodo-O
2.我们将要使用MongoMapper来驱动MongoDB到Rails
编辑GemFile,增加下面的内容
gem"mongo_mapper"
然后 执行bundleinstall安装gem
bundleinstall
3.添加数据库链接
在config/initializer下面新建一个mongo.rb文件,指定全局的数据库信息:
MongoMapper.connection=Mongo::Connection.new('localhost',27017) MongoMapper.database='todo'#通过指定Rails运行环境参数,我们可以在不同的运行环境下创建互不干扰的数据,为了简单起见,没有为不同的环境指定不同的数据
ifdefined?(PhusionPassenger) PhusionPassenger.on_event(:starting_worker_process)do|forked| MongoMapper.connection.connectifforked end end
完成以上步骤后,启动程序:
$railsserver
**Notice:Cextensionnotloaded.ThisisrequiredforoptimumMongoDBRubydriverperformance. Youcaninstalltheextensionasfollows:
geminstallbson_ext
Ifyoucontinuetoreceivethismessageafterinstalling,makesurethatthe bson_extgemisinyourloadpathandthatthebson_extandmongogemsareofthesameversion. =>BootingWEBrick =>Rails3.0.10applicationstartingindevelopmentonhttp://0.0.0.0:3000 =>Callwith-dtodetach =>Ctrl-Ctoshutdownserver [2011-10-1923:36:14]INFOWEBrick1.3.1 [2011-10-1923:36:14]INFOruby1.9.2(2011-07-09)[x86_64-linux] [2011-10-1923:36:14]INFOWEBrick::HTTPServer#start:pid=19595port=3000
从上面输出中可以看到bson_ext库没有加载。按照提示安装该库即可(别忘了在gemfile中添加gem):
再次启动程序,Notice提示消息消失,启动正常。在浏览器输入:http://127.0.0.1:3000,就可以看到如下页面
4.添加页面和处理逻辑
通过rails的generate命令来生成页面、控制器和模型层文件(个人还是喜欢自己手动创建,这里为了演示方便)
railsgeneratescaffoldprojectname:string--orm=mongo_mapper
由于我们使用mongo作为数据库。那么,我们需要把ActiveRecord的model,改成MongoMapper的类型,也就是把继承关系从ActiveRecord::Base变成MongoMapper::Document。我们使用key这个方法标明该MongoMapper的字段属性。我们的属性是name,再加上这个字段的类型String,那么定义如下:
classProject includeMongoMapper::Document key:name,String end
通过以上的修改,我们就已经拥有了所有添加,更新,删除和列表的操作
5.数据查看
可以通过命令mongo进入mongodb数据库进行数据的查询
mongo//进入数据库 usetodo//切换库 db.projects.find()//执行查询6.其他
MongoMapper和ActiveRecord是完全相同的。甚至,MongoMapper还是支持ActiveRecord的验证方式如下
validates_presence_of:name
由于MongoDB没有schema-less(数据版本记录)我们可以非常容易的添加和更改model的属性,而不需要执行任何migrations的操作。比如,我们需要添加一个priority的属性,我们仅仅需要的是修改Projectmodel如下:
classProject includeMongoMapper::Document key:name,String,:required=>true key:priority,Integer end
表之间的关联对于MongoDB这里稍微有点区别,我们需要ObjectId类型来存储所有id。
至于,处理不同表之前的关联,我们可以像ActiveRecord一样定义belongs_to,当然,稍微有点不同,在Project中我们需要定义has_many:tasks,在MongoMapper中需要用many代替。
我目前也就做到这里。有时间再去深入研究其他的功能。
PS:Ruby编写MongoDB备份脚本(fsync&lock)
#!/usr/local/bin/ruby #date:06-12-2014 #auther:lucifer #usefsyncandlocktothefile-systembeforebackupthefile-system #mongo-ruby-driverversion>1.10.0 require'mongo' require'fileutils' require'date' includeMongo includeBSON #themembersofreplcation-set #testmongodbserverversion2.6.0 #host="192.168.11.51" #Theportofmembers #Iftheportis27017bydefaultthenotherportdon'tneedtoassignment #otherport="" #port=otherport.length!=0?otherport:MongoClient::DEFAULT_PORT #opts={:pool_size=>5,:pool_timeout=>10} #Createanewconnection #client=MongoClient.new(host,port,opts) uri_string="mongodb://caoqing:xxxxxxxx@x.x.x.x:27017/admin" client=MongoClient.from_uri(uri="#{uri_string}") db=client['admin'] #fsyncandlockthedatabase cmd=OrderedHash.new cmd[:fsync]=1 cmd[:lock]=true #pcmd db.command(cmd) #datafilepath d="/var/lib/mongo" #dir=Dir.new("#{d}") #entries=dir.entries #entries.delete_if{|entry|entry=~/^\./} #converttherelativepathtothefullpath #entries.map!{|entry|File.join(dir.path,entry)} #maintainonlythetypeoffile #entries.delete_if{|entry|!File.file?(entry)} #pentries start=Date.today.to_s prev=(Date.today-7).to_s dest="/backup/#{start}" sour="/backup/#{prev}" FileUtils.rm_rf("#{sour}")ifFile::exist?("#{sour}") Dir.mkdir("#{dest}",0755)unlessFile::exist?("#{dest}") FileUtils.cp_rDir.glob("#{d}/**"),destifclient.locked? puts"*"*20 puts"\tbackupcomplete" puts"*"*20 #DB::SYSTEM_COMMAND_COLLECTION #unlockthedatabase db["$cmd.sys.unlock"].find_one client.close