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