2019年6月9日日曜日

Sinatra で ActiveRecord を使ってみる

概要

Sinatra で ActiveRecord が使える gem があります
今回はこれを使って sqlite3 のマイグレーションと CRUD をやってみました

環境

  • macOS 10.14.5
  • sqlite3 3.24.0
  • Ruby 2.6.2p47
    • activerecord 5.2.3
    • sqlite3 1.4.1

準備

まずは必要な gem をインストールします

  • bundle init
  • vim Gemfile
gem "rake"
gem "sqlite3"
gem "sinatra"
gem "sinatra-contrib"
gem "sinatra-activerecord"
  • bundle install --path vendor

sinatra-contrib 以外は必須です
rakeactiverecord を使ったデータベースのマイグレートに使います

アプリ作成

次にアプリを作成します
sqlite3 を使うことを明記します
先にモデルを使ってデータを返す処理も実装しています

  • vim app.rb
require 'sinatra'
require 'sinatra/json'
require "sinatra/activerecord"
require './models/user.rb'

class DBTestApp < Sinatra::Base
  register Sinatra::ActiveRecordExtension
  set :database, {:adapter => "sqlite3", :database => "usersdb.sqlite3"}

  get '/' do
    ret = {:key => 'value'}
    json ret
  end

  get '/users' do
    @users = User.all
    json @users
  end
end

/ は特に何もしていません
/users にアクセスした場合は sqlite3 からユーザの一覧を取得して JSON 形式で返却します

あとはアプリを起動するための rackup ファイルも作成しておきます

  • vim config.ru
require './app.rb'
run DBTestApp

No connection pool with 'primary' found

activerecord + sqlite3 を使う場合によく発生するエラーのようです
sqlite3 の gem のバージョンを 1.3 系に固定するなどの対処方法をよく見ましたが自分の場合は register Sinatra::ActiveRecordExtension を app.rb に記載することで発生しなくなりました

モデル作成

アプリ内で使用しているモデルを作成します

  • mkdir models
  • vim models/user.rb
class User < ActiveRecord::Base
end

今回は特に制約などはないので側だけ作成しています

DB マイグレート

アプリの準備ができたらデータベースを作成します
今回は sqlite3 を使います
まずはデータベースをマイグレートするためのタスクを Rakefile に定義します

  • vim Rakefile
require "sinatra/activerecord/rake"

namespace :db do
  task :load_config do
    require "./app.rb"
  end
end
  • bundle exec rake -T

この段階でタスクの一覧が表示されることを確認します
次にマイグレートファイルを作成します

  • bundle exec rake db:create_migration NAME=create_users

db/migrate 配下にマイグレートファイルが作成されるので編集しましょう
今回はシンプルに name フィールドをだけを持つデータベースを作成します

  • vim db/migrate/20190606232247_create_users.rb
class CreateUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
      t.string :name
    end
  end
end

これでマイグレートの準備ができました
db:migrate しましょう

  • bundle exec rake db:migrate

これで DB のマイグレートが行われ usersdb.sqlite3 というファイルが作成されるはずです

動作確認

  • bundle exec rackup config.ru

curl localhost:9292/users にアクセスすると空の配列が返ってくると思います
データを追加してみましょう

$ sqlite3 usersdb.sqlite3 
SQLite version 3.24.0 2018-06-04 14:10:15
Enter ".help" for usage hints.
sqlite> .table
ar_internal_metadata  schema_migrations     users               
sqlite> .schema users
CREATE TABLE IF NOT EXISTS "users" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar);
sqlite> insert into users values (null, "hawk");
sqlite> insert into users values (null, "snowlog");

これで再度アプリを起動して curl すると以下のようなデータが返ってくるはずです

[{"id":1,"name":"hawk"},{"id":2,"name":"snowlog"}]

最後に

Sinatra + ActiveRecord を試してみました
一部ハマる点がありましたがそれ以外は普通の ActiveRecord と同じように使えました
Rails 以外でも Ruby の場合 ORM は基本 ActiveRecord を使うので慣れておいて損はないと思います

参考サイト

0 件のコメント:

コメントを投稿