当前位置:首页 > 开发 > 编程语言 > Ruby > 正文

Rails3.1 使用mongodb学习笔记之mongo_maper

发表于: 2012-03-09   作者:hotsunshine   来源:转载   浏览次数:
摘要: 根据官网的提示按照下面步骤依次进行,官网上的介绍文章用的是mongo_mapper但是我在网上查资料的时候发现很多人都是推荐mongoid的,本着学习,多学一点没坏处的想法,就硬着头皮弄了一遭,过几天再试一试mongoid: 安装rails gem install rails 配置应用程序 很重要的一步就是要跳过这个active-record rails new proj
根据官网的提示按照下面步骤依次进行,官网上的介绍文章用的是mongo_mapper但是我在网上查资料的时候发现很多人都是推荐mongoid的,本着学习,多学一点没坏处的想法,就硬着头皮弄了一遭,过几天再试一试mongoid:
安装rails
gem install rails

配置应用程序
很重要的一步就是要跳过这个active-record
rails new project_name --skip-active-record

如果是没有进行上一步而直接创建了rails项目,可以通过修改 config/application.rb 文件

#  require "rails/all" # 删除掉

# 添加下面
require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"
require "rails/test_unit/railtie"


同时要确保generate命令,不要去对对象关联active_record的orm

# Configure generators values. Many other options are available, be sure to check the documentation.
# config.generators do |g|
#   g.orm             :active_record
#   g.template_engine :erb
#   g.test_framework  :test_unit, :fixture => true
# end



安装gem初始化数据库

Gemfile中添加
source 'http://gemcutter.org'
require 'rubygems'
require 'mongo'
gem "rails", "3.1.0"
gem "mongo_mapper"

接下来运行指令安装gem
bundle install

如果提示没有bundle那么请先安装
gem install bundle


数据库:
创建文件config/initializers/mongo.rb添加内容:

MongoMapper.connection = Mongo::Connection.new('localhost', 27017)
MongoMapper.database = "project_name_#{Rails.env}"

if defined?(PhusionPassenger)
   PhusionPassenger.on_event(:starting_worker_process) do |forked|
     MongoMapper.connection.connect if forked
   end
end


测试配置

创建文件 lib/tasks/mongo.rake 添加内容:

namespace :db do
  namespace :test do
    task :prepare do
      # Stub out for MongoDB
    end
  end
end


--------------------------------------------------------------------
中间遇到的问题以及解决过程

问题一、运行rails s ,出现错误提示:
**Notice: C extension not loaded. This is required for optimum MongoDB Ruby driver performance.
  You can install the extension as follows:
  gem install bson_ext

  If you continue to receive this message after installing, make sure that the
  bson_ext gem is in your load path and that the bson_ext and mongo gems are of the same version.

gems/ruby-1.9.2-p180/gems/execjs-1.3.0/lib/execjs/runtimes.rb:50:in `autodetect': Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)
	from /home/chinacheng/.rvm/gems/ruby-1.9.2-p180/gems/execjs-1.3.0/lib/execjs.rb:5:in `<module:ExecJS>'
	from /home/chinacheng/.rvm/gems/ruby-1.9.2-p180/gems/execjs-1.3.0/lib/execjs.rb:4:in `<top (required)>'


提示缺少gem包
 gem install bson_ext

安装之后,再运行,仍然出现上面这个错误
在Gemfile中添加
gem "bson_ext"

执行rails s
**Notice: C extension not loaded 这个问题就不存在了

还剩下JavaScript runtime这个错误,查了一下原因是:
Windows下默认有Javascript引擎,所以window下不会有这个错误。Linux下才有这个错误,一般只要第一个项目安装即可,以后的项目不用重复安装。
而且这个错误是由development环境中的assets包引起的,注释掉
# Gems used only for assets and not required
# in production environments by default.
#group :assets do
#  gem 'sass-rails', "  ~> 3.1.0"
#  gem 'coffee-rails', "~> 3.1.0"
#  gem 'uglifier'
#end

就不用安装’execjs’和’therubyracer’了。
当然这不是一个好办法
如果不注释,需要在Gemfile中添加
gem 'therubyracer'
gem 'execjs'

或者是安装一个Node.js

问题二:配置文件中hash的问题
ps:关于hash,因为工作原因,我本地既有ruby1.8又有ruby1.9
这个config/initializers/wrap_parameters.rb文件,如果是在ruby1.8.7中会出现如下错误:
 syntax error, unexpected ':', expecting kEND (SyntaxError)
  wrap_parameters format: [:json]

这个在ruby1.9.2环境中是没问题的
1.8环境下需要改成
wrap_parameters :format=>[:json]


另外session_store.rb这个文件中也会出现这个类似的问题:
 
syntax error, unexpected ':', expecting $end (SyntaxError)
...ion_store :cookie_store, key: '_project_name_session'

同理在1.9中没问题,1.8中要改成:key=>'_project_name_session'

上面这个问题突出的问题是:ruby1.8于ruby1.9在hash定义上出现的变化

#新的语法
h = { a: 1, b: 2 }# 

#旧的语法
h = { :a=> 1, :b=>2 }# 返回{:a=>1, :b=>2}

1.9.2同时兼容以前1.8.7的写法

----------------------------------------------------------------------------
接下来继续做那个demo

首先做一下首页的显示
运行指令
rails g controller index

创建index的控制器以及其他代码

先写测试

在控制器的测试文件中添加

 require 'test_helper'
 class IndexControllerTest < ActionController::TestCase
   test "access the index page" do
      get :index
      assert_response 200
   end
 end

运行,肯定跑不通,写代码来实现功能

删除public下面的index.html文件
配置以下路由,指定新的主页路径
root :to=>'index#index'


在IndexController中添加主页action
  class IndexController < ApplicationController
     def index
     end
  end

在app/view/index/下面添加index.erb文件

运行rake test,显示错误
test_helper.rb:3:in `<class:TestCase>': undefined method `fixtures' for ActiveSupport::TestCase:Class (NoMethodError)

这是测试用例的问题
把test_helper.rb中调用测试用例的代码注释掉
# fixtures :all

再次运行测试rake test

IndexControllerTest
     PASS test_access_the_index_page (0:00:00.334)
Finished in 0.335200 seconds.
1 tests, 1 passed, 0 failures, 0 errors, 0 skips, 1 assertions

访问主页成功

ps:上面的controller基本上跟mongo没啥关系,但是考到功能测试出现的这fixtures还是把这个放上来了

模型
创建一个名为user的model:执行命令
rails g model topic --skip-migration  --orm=mongo_mapper

orm这个参数如果不写,会出现这个错误
No value provided for required options '--orm'

执行完成之后显示生成的文件:
      invoke  mongo_mapper
      create    app/models/user.rb
      invoke    test_unit
      create      test/unit/user_test.rb
      create      test/fixtures/users.yml

如果不想每一次都写这个--orm
在config/application.rb中添加:

config.generators do |g|
  g.orm :mongo_mapper
end


user.rb代码
class User
  include MongoMapper::Document
  key :name, String
  key :age, Integer
end

user_test.rb代码

# encoding: utf-8
require 'test_helper'

class UserTest < ActiveSupport::TestCase
  test "new user test" do
    assert_equal User.count,0
    assert_difference "User.count",1 do
      User.create(:name=>"王华",:age=>18)
    end
    user = User.last
    assert_equal user.name, "王华"
    assert_equal user.age, 18
  end


运行单元测试
rake test:units 发现错误
Errors running test:units!
查看堆栈得到信息
** Invoke test:units (first_time)
** Invoke test:prepare (first_time)
** Invoke db:test:prepare (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute db:test:prepare
rake aborted!
Set config before connecting. MongoMapper.config = {...}


提示在链接之前先配置:
project_name$ script/rails generate mongo_mapper:config
      create  config/mongo.yml


此配置文件的内容是:


development:
  host: 127.0.0.1
  port: 27017
  database: project_name_development

test:
  host: 127.0.0.1
  port: 27017
  database: project_name_test

# set these environment variables on your prod server
production:
  host: 127.0.0.1
  port: 27017
  database: project_name
  username: <%= ENV['MONGO_USERNAME'] %>
  password: <%= ENV['MONGO_PASSWORD'] %>


rake test;units是没有问题了

UserTest
     PASS test_new_user_test (0:00:00.333)

Finished in 0.469750 seconds.

1 tests, 1 passed, 0 failures, 0 errors, 0 skips, 4 assertions



另外还写了一个users_controller的增删该查以及它的测试,跟mysql关联的写法没有任何区别,完全一样。

测试项目源码地址
https://github.com/chinacheng/mongodb_project

Rails3.1 使用mongodb学习笔记之mongo_maper

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
Inserting Document-Orientation 在描述中,MongoDB是面向文档的,意味着在这种数据库中主要存储单
MongoDB学习笔记之 第1章 MongoDB的安装 MongoDB学习笔记之 第2章 MongoDB的增删改查 MongoDB学习笔
MongoDB学习笔记之 第1章 MongoDB的安装 MongoDB学习笔记之 第2章 MongoDB的增删改查 MongoDB学习笔
MongoDB学习笔记之 第1章 MongoDB的安装 MongoDB学习笔记之 第2章 MongoDB的增删改查 MongoDB学习笔
MongoDB学习笔记之 第1章 MongoDB的安装 MongoDB学习笔记之 第2章 MongoDB的增删改查 MongoDB学习笔
1. Mac 安装mongodb:   官网下载mac版mongodb,解压到本地目录,如/Applications/mongodb,注意这
sharding(分片功能) 手动分片:所有数据库都支持,但是需要应用程序自行维护连接、存储和查询,难以
一、前言   最近开始学习非关系型数据库MongoDB,却在博客园上找不到比较系统的教程,很多资料都
MongoDB的设计理念:能从服务器端转移到驱动程序来做的事,就尽量转移。 文档是MongoDB的核心概念。
MongoDB中使用find来进行查询,查询就是返回一个集合中文档的子集,子集合的范围从0个文档到整个集
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号