天天看點

使用MySQL+DataMapper為Ruby Web應用增加資料庫存儲

在之前搭建的簡單Ruby Web應用基礎上增加資料庫存儲:

工具集:

  • DataMapper — ORM架構
  • MySQL — 資料庫

步驟:

  1. 引入data_mapper、dm-mysql-adapter、dm-migrations、haml等gem,并

    bundle install

    安裝:
    # Gemfile
    source 'http://ruby.taobao.org/'
    gem 'sinatra'
    gem 'unicorn'
    gem 'capistrano', '~> 2.15.5'
    gem 'rvm-capistrano'
    gem 'data_mapper'
    gem 'dm-mysql-adapter'
    gem 'dm-migrations'
    gem 'haml'
               
  2. 新增模型類。假設要增加一個簡單的功能,使用者在頁面上通過表單輸入一個字元串作為關鍵字,每送出一次,應用就将該關鍵字記錄下來存儲到資料庫中,模型類如下:
    # models/history.rb
    class History
      include DataMapper::Resource
    
      property :id,               Serial
      property :keyword,          String
      property :created_at,       DateTime, :default => lambda { |r,p| Time.now }
    
    end
               
    增加一段連接配接MySQL以及建立對象-關系映射的初始化代碼,注意:
    • DataMapper.finalize

      要在所有的模型類都已被引入之後調用
    • DataMapper.auto_upgrade!

      執行時會自動根據模型類對資料庫進行migration更新操作,與

      DataMapper.auto_migrate!

      方法不同的是,

      auto_upgrade!

      僅會更新資料庫表結構而不抹除已有資料,

      auto_migrate!

      則會調整表結構并抹除已有資料。
    # models/init.rb
    require 'data_mapper'
    require 'dm-migrations'
    require_relative 'history'
    
    # A MySQL connection:
    DataMapper.setup(:default, 'mysql://[email protected]/test') # Your mysql username and database
    DataMapper.finalize
    DataMapper.auto_upgrade!
               
    并在app.rb中引入models/init.rb檔案:
    # app.rb
    require 'sinatra'
    
    class App < Sinatra::Base
      get '/' do
        'Hello world'
      end
    end
    
    require_relative 'models/init'
               
  3. 新增模闆檔案。這裡使用一個haml檔案,包括一個簡單的表單和送出按鈕,供使用者送出關鍵字。模闆檔案如下:
    # views/search.haml
    !!!
    %html
      %head
      %body
        %h3 Search
        %form.form{:action => '#', :method => 'get'}
          %fieldset
            %legend Keyword Input
            %ul
              %li
                %input#keyword{:type => 'text', :name => 'q', :value => params[:q]}
              %li
                %input{:type => 'submit', :value => 'Search'}
               
  4. 新增一個routes檔案,用于響應表單送出請求:
    # routes/search.rb
    class App < Sinatra::Base
    
      get '/search' do
        q = params[:q]
        History.create(:keyword => q) unless q.nil? or q.strip.empty?
        haml :search
      end
    
    end
               
    # routes/init.rb
    require_relative 'search'
               
    另外

    app.rb

    中需

    require_relative 'routes/init'

    增加對routes檔案的引入。
  5. push代碼到git倉庫後使用

    cap deploy

    進行部署。在正式部署之前需先在遠端主機上安裝mysql,部署時如果有類似于以下的報錯:
    servers: ["115.28.137.21"]
      [[email protected]] executing command
    ** [out :: [email protected]] Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
    ** [out :: [email protected]] 
    ** [out :: [email protected]] checking for main() in -lmysqlclient... no
    ......
    ** [out :: [email protected]] make failed, exit code 2
    ** [out :: [email protected]] 
    ** [out :: [email protected]] Gem files will remain installed in /srv/dev-helper/shared/bundle/ruby/1.9.1/gems/do_mysql-0.10.13 for inspection.
    ** [out :: [email protected]] Results logged to /srv/dev-helper/shared/bundle/ruby/1.9.1/extensions/x86_64-linux/1.9.1/do_mysql-0.10.13/gem_make.out
    ** [out :: [email protected]] An error occurred while installing do_mysql (0.10.13), and Bundler cannot
    ** [out :: [email protected]] continue.
    ** [out :: [email protected]] Make sure that `gem install do_mysql -v '0.10.13'` succeeds before bundling.
               
    多是因為找不到mysql安裝路徑所緻,可以在遠端主機上運作:
    bundle config build.do_mysql --with-mysql-config=/usr/bin/mysql
               
    然後再進行部署。部署成功後就可以看到新功能生效了。

參考:

  • Getting started with DataMapper
  • Fixing bundle install/update of do_mysql on Mac OS X