ただ簡単なAPIっぽいのが作りたかっただけなんです。途中まではハマリもなくすんなり行きました。でも、ハマったんです。localのsqlite3のデータをherokuのpostgreSQLに挿入するのがうまく行かなかったんです。
が、なんとか問題はクリアしたのでその顛末を記してみます。僕はRubyもActiveRecordもherokuもPostgreSQLもその他もろもろ素人なので他にもっと良い方法があると思うので、ご意見いただきたいです。
まずはローカルの環境をSinatraで作成する
このような形で作成しました。ここまではすんなり行きました。
herokuのPostgreSQLの環境にデプロイする
ここで激しくハマリました。PostgreSQLでローカルと同じデータベースを起動させるところまでは行ったのですが、中のマスターデータをPostgreSQLに移行することができなかった。とりあえず、herokuのPostgreSQLでCSVを読みこめばいいと割りきってやったのでそこまでの顛末を書きます。
Gemfile
こんな感じにしました。ポイントはdevelopmentとproductionでgemを分けているところです。herokuではpostgreSQLで行います。
source "https://rubygems.org" ruby '2.0.0' gem "sinatra" gem "sinatra-contrib" gem "sinatra-activerecord", :require => 'sinatra/activerecord' gem "activerecord" gem "rake" group :development do gem 'sqlite3' end group :production do gem 'pg' gem "activerecord-postgresql-adapter" end
Rakefile
リンクを参考にこんな形にしました。Rakefileって初めて作成したんですが、これを作成すると、rakeコマンドが使えるようになるんですね。
require 'sinatra' require 'sinatra/activerecord' require 'sinatra/activerecord/rake'
main.rb
“/”はテスト用です。目的は”/countries/”を動作させることでした。
require "sinatra" require "sinatra/reloader" require "active_record" require "sinatra/json" ActiveRecord::Base.establish_connection(ENV['DATABASE_URL'] || 'sqlite3://localhost/development.db') class Country < ActiveRecord::Base end get '/' do "Hello World" end get '/countries' do @countries = Country.order("id asc").to_a countries = Array.new() @countries.each do |country| countries.push({id: country.id, name: country.name, color: country.color}) end output = {countries: countries} json output end
config/database.yml
productionの接続情報は、https://dashboard.heroku.com/apps
で確認することができます。
development: adapter: sqlite3 database: development.db test: adapter: sqlite3 database: test.db production: adapter: postgresql host: [herokuの情報] port: [herokuの情報] database: [herokuの情報] username: [herokuの情報] password: [herokuの情報]
ActiveRecordのマイグレーションファイルを作成
ActiveRecordの意味がわかっていなかったのでこれをやる必要が有ることに気づけませんでした。
SinatraからActiveRecord 3を使う(1) マイグレーション - アインシュタインの電話番号
こちらを参考にmigrationファイルを作成しました。ローカルでプロジェクトを作成した時には、手作りファイルからdbの構造を設定していましたが、ActiveRecord経由で設定することにしました。このmigrationファイルがあればローカルと同じ環境をherokuのpostgreSQLでも作れるんですね。
デプロイ
【Sinatra】ローカルではSQLiteで開発して、HerokuではPostgreSQLで運用をする方法 〜Herokuへデプロイ - Try to try
基本的にこちらのサイトを参考にさせていただきました。rake
とあるところは、僕の環境ではbundle exec rake
をする必要がありました。ここでherokuでpostgreSQLを使えるようにして、データベースの構造を作成するところまで行います。
マスターデータの挿入
デプロイのところではpostgreSQLのデータベースを作成するところまでしかできません。マスターデータの挿入ですが、ローカルのsqlite3のデータを移行する方法を探しましたが、なかなかうまく行きません。。。そこで、考え方を変えてheroku側でもローカルと同じようにcsvから読み込んじゃえばいいじゃないか、とりあえず!という方針に転換しました。
$ heroku pg:psql
を行い、herokuのpostgreSQLにアクセスします。
=> \copy countries from 'countries.csv' CSV;
こんな感じでcountriesのCSVを読み込むことが出来ました。
=> select * from countries; id | name | color ----+---------+-------- 0 | Japan | red 1 | US | blue 2 | Britain | yellow 3 | France | purple 4 | Germany | green 5 | China | orange 6 | India | brown (7 rows)
なんとかマスターデータを更新することが出来ました。。。いろいろ下調べせずにいきなりやったのでちょっと大変でした。うーん、これはまだ気楽に使えるというレベルではないなぁ。herokuじゃなくて、自分のvpsでsqliteでやれば簡単に行きそうだけど。