高木のブログ

Sinatraでデータベースを使う(SQLite3 + ActiveRecord)

2022/04/27

Sinatraで作っているAPIでデータベースを使うことになり、SQLite3 と ActiveRecord を導入した時のメモ

Sinatra の README.md に書いてある手順だけですんなり導入できた

手順

Sinatra をクラシックスタイルで使っている場合のやり方

セットアップ

Gemを追加

必要なGemを追加する

Gemfile
+gem 'sinatra-activerecord'
+gem 'sqlite3'
+gem 'rake'

rake はデータベースの作成やマイグレーションを行うためのRakeタスクのために必要

データベースの設定を追加

Rails でお馴染みのやつ
とりあえず最低限の設定だけ記述した

config/database.yml
development:
  adapter: sqlite3
  database: db/development.sqlite3

production:
  adapter: sqlite3
  database: db/production.sqlite3

Rakeタスクの設定を追加

Rakefile
require 'sinatra/activerecord/rake'

namespace :db do
  task :load_config do
    require './app'
  end
end

動作確認

$ bundle exec rake -T
rake db:create              # Creates the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:create:all to creat...
rake db:create_migration    # Create a migration (parameters: NAME, VERSION)
rake db:drop                # Drops the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:drop:all to drop all ...
rake db:encryption:init     # Generate a set of keys for configuring Active Record encryption in a given environment
rake db:environment:set     # Set the environment value for the database
rake db:fixtures:load       # Loads fixtures into the current environment's database
rake db:migrate             # Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)
rake db:migrate:down        # Runs the "down" for a given migration VERSION
rake db:migrate:redo        # Rolls back the database one migration and re-migrates up (options: STEP=x, VERSION=x)
rake db:migrate:status      # Display status of migrations
rake db:migrate:up          # Runs the "up" for a given migration VERSION
rake db:prepare             # Runs setup if database does not exist, or runs migrations if it does
rake db:reset               # Drops and recreates all databases from their schema for the current environment and loads the seeds
rake db:rollback            # Rolls the schema back to the previous version (specify steps w/ STEP=n)
rake db:schema:cache:clear  # Clears a db/schema_cache.yml file
rake db:schema:cache:dump   # Creates a db/schema_cache.yml file
rake db:schema:dump         # Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_...
rake db:schema:load         # Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_fo...
rake db:seed                # Loads the seed data from db/seeds.rb
rake db:seed:replant        # Truncates tables of each database for current environment and loads the seeds
rake db:setup               # Creates all databases, loads all schemas, and initializes with the seed data (use db:reset to also drop all databas...
rake db:version             # Retrieves the current schema version number

タスクがズラーっと表示されたら準備完了

データベースの作成

Rails でお馴染みのコマンドで作成できる

$ bundle exec rake db:create
Created database 'db/development.sqlite3'

db ディレクトリはなかったら自動で作られる

テーブルの作成

試しに users テーブルを作ってみる

マイグレーションファイルの作成

$ bundle exec rake db:create_migration NAME=create_users
db/migrate/20220423133230_create_users.rb

db/migrate ディレクトリもなかったら自動で作られる

db/migrate/20220423133230_create_users.rb
 class CreateUsers < ActiveRecord::Migration[7.0]
   def change
+    create_table :users do |t|
+      t.string :name
+    end
   end
 end

マイグレート

$ bundle exec rake db:migrate
== 20220423133230 CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.0192s
== 20220423133230 CreateUsers: migrated (0.0197s) =============================

確認

$ sqlite3 db/development.sqlite3
sqlite> .schema users
CREATE TABLE IF NOT EXISTS "users" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar);
sqlite> insert into users(name) values('たろう');
sqlite> insert into users(name) values('じろう');
sqlite> select * from users;
1|たろう
2|じろう

モデルの作成

models ディレクトリはなかったら自分で作る

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

実際にアプリケーションからデータベースに接続して、レコードを取ってくる

必要な Gem とモデルをrequireして、usersテーブルのレコードを全件返すエンドポイント /users を作る

app.rb
 require 'sinatra'
+require 'sinatra/activerecord'
+require_relative 'models/user'

+get '/users' do
+  users = User.all
+  users.to_json
+end
$ curl -s localhost:4567/users | jq
[
  {
    "id": 1,
    "name": "たろう"
  },
  {
    "id": 2,
    "name": "じろう"
  }
]

いい感じ

参考

hawksnowlog: Sinatra で ActiveRecord を使ってみる


ytkg

Written by ytkg, Twitter, GitHub