発声練習

2010-09-17

[][] Rails 3.0インデックス

自分のメモのために自分で書いた Ruby on Rails 3.0のエントリーについてインデックス化しておく。

[][] Debian GNU/Linux Squeezeで Rails 3.0 + PostgreSQL

Rails 3.0のインストールはこちらを参照のこと。

PostgreSQLのインストールとデータベース作成

% sudo aptitude install postgresql

PostgreSQLのスーパーユーザー(サーバーのスーパーユーザーではない)は、postgresなので、新たなユーザーやデータベースを作るときには、postgresになる。

% sudo su
% su postgres
% exit (rootに戻るとき)
% exit (元のユーザーに戻るとき)

自分のログインアカウント(仮にhogehogeとする)をPostgreSQLのユーザーとして加えたい場合は以下のようにする。

% sudo su
% su postgres
% createuser hogehoge
(スーパーユーザー権限、データベース作成権限、ロール作成権限について聞かれる。)
% exit (rootに戻るとき)
% exit (元のユーザーに戻るとき)

Railsプロジェクトからアクセスするためのユーザーとデータベースを作成する。

  • ユーザー名: hogehoge_rails
  • ログインパスワード: 12345
  • データベース名: hogehoge_rails_db

コマンドは以下のとおり。

% sudo su
% su postgres
% createdb --encoding="utf-8" -T template0 hogehoge_rails_db
% psql hogehoge_rails_db
> \l (データベースの一覧を確認)
> CREATE ROLE hogehoge_rails WITH LOGIN PASSWORD '12345';
> GRANT ALL ON DATABASE hogehoge_rails_db to "hogehoge_rails";
> \q (psqlの終了)
% exit
% exit

Railsプロジェクトの設定

app_30というプロジェクトが既にあるとする。

まずは、RubyからPostgreSQLを使うためのライブラリーのインストール。

% sudo gem1.8 install pg

app_30/Gemfileにpgを追加。本番環境はPostgreSQL、開発環境はSQLite3を使うときは以下のようにする。

group :development do
 gem 'sqlite3-ruby', :require => 'sqlite3'
end

group :production do
 gem 'pg'
end

Gemfile.lockを生成する。

% bundle install --local --without development

app_30/config/database.ymlを編集する。productionの部分を以下のようにする。

production:
  adapter: postgresql
  database: hogehoge_rails_db
  username: hogehoge_rails
  password: 12345
  host: localhost
  encording: utf8

環境変数のRackEnvがproductionになっていることを確かめる。使用しているシェルがcshやtcshならば.cshrcに以下のように書き加える。

setenv RackENV production

bashの場合は、.bashrcに以下を書き加える。

RAILS_ENV=production
export RAILS_ENV

設定ファイルを読み込む。

% source ~/.cshrc (csh, tcshの場合)
% source ~/.bashrc  (bashの場合)

データベースの作成を行う。

% cd app_30
% rake db:migrate

うまくテーブルが生成されていれば成功。

% sudo su
% su postgres
% psql hogehoge_rails_db
> \dt (テーブルの一覧表示)
> \q (psqlの終了)
% exit
% exit

追記(2010年10月5日): db:migrate:resetがうまくいかない

このやり方で作ったデータベースとユーザーでは、db:migrate:resetを行おうとすると失敗する。db:migrate:resetは以下の手順で進む。

  1. データベースの削除
  2. データベースの作成
  3. テーブルの作成

このとき、データベースの作成ができない。

# rake db:migrate:reset
(in /home/hogehoge/railstop/trunk)
PGError: ERROR:  new encoding (UTF8) is incompatible with the encoding of the template database (SQL_ASCII)
HINT:  Use the same encoding as in the template database, or use template0 as template.
: CREATE DATABASE "hogehoge_rails_db" ENCODING = 'utf8'
/usr/lib/ruby/gems/1.8/gems/activerecord-3.0.0/lib/active_record/connection_adapters/abstract_adapter.rb:202:in `log'
/usr/lib/ruby/gems/1.8/gems/activerecord-3.0.0/lib/active_record/connection_adapters/postgresql_adapter.rb:496:in `execute'
/usr/lib/ruby/gems/1.8/gems/activerecord-3.0.0/lib/active_record/connection_adapters/postgresql_adapter.rb:575:in `create_database'
/usr/lib/ruby/gems/1.8/gems/activerecord-3.0.0/lib/active_record/railties/databases.rake:92:in `create_database'
/usr/lib/ruby/gems/1.8/gems/activerecord-3.0.0/lib/active_record/railties/databases.rake:35
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:636:in `call'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:636:in `execute'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:631:in `each'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:631:in `execute'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:597:in `invoke_with_call_chain'
/usr/lib/ruby/1.8/monitor.rb:242:in `synchronize'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:590:in `invoke_with_call_chain'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:607:in `invoke_prerequisites'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:604:in `each'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:604:in `invoke_prerequisites'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:596:in `invoke_with_call_chain'
/usr/lib/ruby/1.8/monitor.rb:242:in `synchronize'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:590:in `invoke_with_call_chain'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:583:in `invoke'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2051:in `invoke_task'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2029:in `top_level'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2029:in `each'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2029:in `top_level'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2068:in `standard_exception_handling'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2023:in `top_level'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2001:in `run'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2068:in `standard_exception_handling'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:1998:in `run'
/usr/lib/ruby/gems/1.8/gems/rake-0.8.7/bin/rake:31
/usr/bin/rake:19:in `load'
/usr/bin/rake:19
Couldn't create database for {"username"=>"hogehoge_rails", "adapter"=>"postgresql", "encording"=>"utf8", "database"=>"hogehoge_rails_db", "host"=>"localhost", "password"=>"12345"}
rake aborted!
FATAL:  database "hogehoge_rails_db" does not exist

(See full trace by running task with --trace)

エラーメッセージを見るかぎりPostgreSQLでは、データベース作成時にテンプレートを参照することになっているがそれができていないのが原因らしい。

/usr/lib/ruby/gems/1.8/gems/activerecord-3.0.0/lib/active_record/connection_adapters/postgresql_adapter.rbのcreate_databaseというメソッドを見るかぎり、templateというオプションを指定してやればちゃんとしたSQLを出力できる様子。そこで、/usr/lib/ruby/gems/1.8/gems/activerecord-3.0.0/lib/active_record/railties/databases.rakeをちょっと編集することにする。

% cp /usr/lib/ruby/gems/1.8/gems/activerecord-3.0.0/lib/active_record/railties/databases.rake lib/tasks/mydb.rake

以下のように変更する。

% diff databases.rake mydb.rake 
1c1
< namespace :db do
---
> namespace :mydb do
92c92
<           ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => @encoding))
---
>           ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => @encoding, 'template' => 'template0'))

以下のようにコマンドを打つとPostgreSQLでデータベースを作成できる。

% rake mydb:migrate:reset

[] Ruby on Rails 3.0で本番環境はPostgreSQL、開発環境はSQLite3を使うとき

2系ならば、config/database.ymlの設定だけで変更可能だが、Rails 3.0ではBundleでgemライブラリーを管理するため、本番環境と開発環境で、読み込むライブラリーを変える必要がある。

Bunlde: Gemfileによると、プラットフォームや環境の違いにより読み込むライブラリーの変更が可能。Gemfileに以下のように記載する。

group :development do
 gem 'sqlite3-ruby', :require => 'sqlite3'
end

group :production do
 gem 'pg'
end

Gemfile.lockを生成するときに以下のように実行する。

% bundle install --local --without development (本番環境)
% bundle install --local --without publication (開発環境)