読者です 読者をやめる 読者になる 読者になる

後ろを向いて後退します

これって前に進んでいることになりませんか?

Sinatra/ActiveRecord

Sinatra + ActiveRecord + MySQL2

SinatraActiveRecordを使ってAPIサーバーのテンプレートを作るのにつまづきまくったので, 適当にメモを残しておきます.

OSはDebian 8 jessieの64bitです. (Windows8.1のVMwarePlayer上で動かしてます.)

1. preparation

  • 1.bundlerが入っていなければインストール.
     $ sudo gem install bundler
  • 2.gemのインストールに必要なパッケージ, mysql-serverをインストールする.
    mysql-serverのインストール時にはrootのパスワードを設定するように促されるが, これは後にdatabase.ymlに設定を書く際に必要となるので覚えておく必要がある.
     $ sudo apt-get install ruby-dev make gcc g++ libmysqlclient15-dev mysql-server

2. local-installing gems

  • 1.用意した適当なディレクトリの中でeditorを開きGemfileを編集する.
     $ vim Gemfile
source 'https://rubygems.org'
ruby '2.1.5'

gem 'sinatra'
gem 'sinatra-contrib'
gem 'activerecord'
gem 'sinatra-activerecord'
gem 'mysql2'
gem 'rake'
gem 'json'
gem 'thin', '~> 1.6.3'
  • 2.Gemfileのあるところでbundle installコマンドを実行する.
     $ bundle install --path vendor/bundle
  • 3.カレントディレクトリ下にvendor/bundle/ruby/2.1.0というディレクトリが階層的に作られ, vendor/bundle/ruby/2.1.0/gemsディレクトリにbundle installコマンドでローカルインストールしたgemが入っていることを確認.

3. editing migration file

  • 1.Gemfileと同じところでRakefileを編集する.
     $ vim Rakefile
require 'sinatra/activerecord'
require 'sinatra/activerecord/rake'
  • 2.rakeタスクを用いてmigration用ファイルを生成する.
     $ bundle exec rake db:create_migration NAME=create_tests
  • 3.カレントディレクトリ下に./db/migrate/[date]_create_tests.rbが生成されるので, それを編集する.
     $ vim ./db/migrate/[date]_create_tests.rb
class CreateTests < ActiveRecord::Migration
    def change
        create_table :tests do |t|
            t.string :name, :null => false, :default => 'hoge'
            t.integer :point, :default => 0
            t.timestamps
        end
    end
end
  • 4.mysqlでデータベースを作成する.
$ mysql -u root -p
# パスワードの入力を要求されるので, mysql-serverインストール時にrootに設定したパスワードを入力
mysql> create database test;
mysql> quit

4. editing 'database.yml' & 'app.rb'

development:
    adapter: mysql2
    database: test
    host: localhost
    username: root
    password: ***
    encoding: utf8
    pool: 5
    reconnect: true

※ '***'にはmysql-serverのrootで設定したパスワードを書く.

  • 3.app.rbを編集する.
     $ vim ./src/app.rb
# coding: utf-8
require 'sinatra'
require 'sinatra/base'
require 'sinatra/reloader'
require 'json'
require 'active_record'
require 'mysql2'

ActiveRecord::Base.configurations = YAML.load_file('./config/database.yml')
ActiveRecord::Base.establish_connection(:development)

class MainApp < Sinatra::Base
    # instantiation of database class
    class Test < ActiveRecord::Base
    end
    # Sinatra Auto Reload
    configure :development do
        register Sinatra::Reloader
    end
    # define methods
    get '/' do
    'Hello World!'
    end
    post '/' do
        'POST request has been sent'
    end
    put '/' do
        'PUT request has been sent'
    end
    delete '/' do
        'DELETE request has been sent'
    end
    get '/test.json' do
        content_type :json, :charset => 'utf-8'
    # add one record to database
        Test.create(:name => 'hoge', :point => 10)
    # get all record from database
        tests_jsonized = Test.all
    # jsonize them
        tests_jsonized.to_json(:root => false)
    end
end
  • 4.Rakefileでapp.rbをrequireし, databaseをmigrateする.
     $ echo "require './src/app.rb'" >> Rakefile
     $ bundle exec rake db:migrate

5. executing server process

  • 1.config.ruを編集する.
     $ vim config.ru
require_relative 'src/app'
run MainApp
./
├── Gemfile
├── Gemfile.lock
├── Rakefile
├── config
│   └── database.yml
├── config.ru
├── db
│   ├── migrate
│   │   └── [date]_create_tests.rb
│   └── schema.rb
├── src
│   └── app.rb
└── vendor
    └── bundle
        └── (略)
  • 3.サーバーを動かす.
     $ bundle exec rackup -o 0.0.0.0
  • 4.ブラウザで接続. jsonが返ってきていればOK.
     $ firefox localhost:9292/test.json

6. summary

  • Gemfile
    ... Bundler用の設定ファイル. 入れたいgemを書いてローカルインストールすると幸せになれる.
  • Rakefile
    ... Rakeというビルドツールのためのビルドを定義するためのファイル. 今回はタスクのrequireしか定義していない.
  • database.yml
    ... MySQL用のデータベース設定ファイル.
  • config.ru
    ... rackupコマンド用の設定ファイル.