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

Ringo-TabberでローカルにPostgreSQLを入れる + Padrino0.11.0への対応を行う

Heroku Padrino Ruby

HerokuとローカルでDBでDBを合わせようと考え、ローカルにPostgreSQLを入れてみました。
その上でデータを投入しようとしたところ、Padrino0.11.0対応が必要になったため、いろいろと修正しました。
そこで、その時のメモを残します。

■環境

その他は、以下の記事同様です。
Ruby + Heroku + Highchartsで食べたリンゴの割合をグラフ化してみた - メモ的な思考的な



■ローカルへPostgreSQLをインストールする

1. apt-getで必要な物を入れる

大したことはやらないだろうと想定の元、apt-getでpostgresqlを入れます。

sudo apt-get install postgresql


続いて、bundle時に例外が起きるのを防ぐため、libpg-devを入れます。

sudo apt-get install libpq-dev


ちなみに、エラー内容は以下の通りです。

Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

        /usr/bin/ruby1.9.1 extconf.rb 
checking for pg_config... yes
Using config values from /usr/bin/pg_config
You need to install postgresql-server-dev-X.Y for building a server-side extension or libpq-dev for building a client-side application.

参考:ruby on rails - cannot install pg gem, checking for PQconnectdb() in -lpq... no - Stack Overflow



2. ローカルのPostgreSQLの設定

まずは、Ubuntu上のpostgresユーザーのパスワードを設定します(ここでは"hoge"とします)。

sudo passwd postgres
新しいUNIXパスワードを入力してください: hoge
新しいUNIX パスワードを再入力してください: hoge
passwd: パスワードは正しく更新されました


PostgreSQL上での管理ユーザーのパスワードを設定します(ここでは"fuga"とします)。

sudo su - postgres
psql -c "alter user postgres with password 'fuga'"
ALTER ROLE


最後に、ローカルで使うdatabaseも作成しておきます(ここでは"herokudev")。

createdb herokudev -E 'utf8';


他に使うコマンドは以下の通りです。

# 作成したdatabaseの確認
psql -l

# 確認するとpsqlに入ったままなので、psqlの終了
\q

# postgresから抜ける
exit
ログアウト


参考:

■PadrinoからローカルのPostgreSQLを使うための設定

config/database.rbの変更

developmentの内容を変更します。

- ActiveRecord::Base.configurations[:development] = {
-  :adapter => 'sqlite3',
-  :database => Padrino.root('db', 'ringo_tabeta_development.db')
- }


+ ActiveRecord::Base.configurations[:development] = {  
+   :adapter  => 'postgresql',  
+   :host     => 'localhost',  
+   :port     => 5432,  
+   :username => 'postgres',  
+   :password => 'fuga',  
+   :database => 'herokudev',  
+   :encoding => 'utf8'
+ }
Gemfileの変更

SQLiteからPostgreSQLへと変更したため、必要なgemを切り替えます。

group :development do
-  gem 'sqlite3'
+  gem 'pg'
end


Gemfileを変更したため、Bundlerを使います。

bundle update


なお、Bundlerを忘れると、seeds.rbの実行時にエラーとなります。
Padrino 0.11.0のおかげで、「/usr/local/bin/padrino:19: stack level too deep (SystemStackError)」ではなく、きちんとエラーが表示されています。

=> Executing Rake seed ...
/var/lib/gems/1.9.1/gems/bundler-1.2.3/lib/bundler/rubygems_integration.rb:147:in `block in replace_gem': Please install the postgresql adapter: `gem install activerecord-postgresql-adapter` (pg is not part of the bundle. Add it to Gemfile.) (LoadError)

■Padrino 0.11.0対応

前回の記事ではPadrinoのバージョンを上げただけであったので、それだけでは足りていない部分を修正していきます。

Rakefileの修正

Padrino 0.11.0にてRakefileのフォーマット変更が入ったため、そちらに対応しておきます。
参考:Blog Padrino 0.11.0 Released - Padrino Lives! - Padrino Ruby Web Framework の「6) New Rakefile format」あたり。


Rakefile

# 以下の一行を削除
- require File.expand_path('../config/boot.rb', __FILE__)

require 'thor'
require 'padrino-core/cli/rake'

# ActiveRecordを使っているため、以下の一行を追加
+ PadrinoTasks.use(:activerecord)

PadrinoTasks.init


修正しない場合、以下のエラーが表示されます。「PadrinoTasks.use(:activerecord)」が消えれば、対応完了だと思います。

Loading database tasks automatically.
This functionality will be disabled in future versions. Please put

  PadrinoTasks.use(:database)
  PadrinoTasks.init

and remove

  require File.expand_path('../config/boot.rb', __FILE__)

in you Rakefile instead.
Loading activerecord tasks automatically.
This functionality will be disabled in future versions. Please put

  PadrinoTasks.use(:activerecord)
  PadrinoTasks.init

and remove

  require File.expand_path('../config/boot.rb', __FILE__)

in you Rakefile instead.
adminページの再生成

adminページがかなり変更されたとのことなので、再生成します。
途中で上書きするかという旨のメッセージが出ますが、すべて「y」にしておきます。

padrino g admin

なお、その影響で、今までのdb/seeds.rbファイルがseeds.oldとなり、新しくseeds.rbファイルが作成されます。

seeds.oldをsees.rbにリネーム

今まで使っていたseeds.rb(現在はseeds.old)は、0.11.0でも使えます。
そのため、新しく生成されたseeds.rbは削除し、seeds.oldをseeds.rbへとリネームしておきます。


bundle exec rake db:migrate時のエラー対応パッチ

画面には

  1) Run 'bundle'
  2) Run 'bundle exec rake db:migrate'
  3) Run 'bundle exec rake db:seed'
  4) Visit the admin panel in the browser at '/admin'


と表示されるため、順番にやったところ、2)の手順でエラーが発生します。

  ERROR -  Cannot require /home/sk/ringo-tabetter/admin/app.rb due to a syntax error: /home/sk/ringo-tabetter/admin/app.rb:44: syntax error, unexpected '\n', expecting tCOLON2 or '[' or '.'
rake aborted!


そのため、一つ一つ修正していきます。
なお、Padrino0.11.0の新規アプリを作り、そちらとの差分をパッチしていくような感じにしています。



admin/app.rbの修正

「44行目あたりでsyntaxエラー」が出ているものの実際のところは、1行目にmodule名が書かれていないのが原因のようなので、書くようにします。

- module
+ module RingoTabeta
app/app.rbの修正

再度bundle exec rake db:migrateをすると、次は以下のエラーとなります。

rake aborted!
RingoTabeta is not a module
/home/sk/ringo-tabetter/admin/app.rb:1:in `'


0.10.7ではclass始まりでしたが、0.11.0ではmoduleの下にclassが書かれるようになったため、修正します。
また、Padrino0.11.0のジェネレーターに合わせて、class名は「App」に変えておきます。

- class RingoTabeta < Padrino::Application

+ module RingoTabeta
+   class App < Padrino::Application
〜略〜
+ end  # 最終行
config/apps.rbの修正

再度bundle exec rake db:migrateをすると、エラー内容がまた変わります。

rake aborted!
Unable to locate app for 'Admin', try with :app_class => 'MyAppClass'
/var/lib/gems/1.9.1/gems/padrino-core-0.11.0/lib/padrino-core/mounter.rb:188:in `ensure_app_object!'
/var/lib/gems/1.9.1/gems/padrino-core-0.11.0/lib/padrino-core/mounter.rb:33:in `initialize'
/var/lib/gems/1.9.1/gems/padrino-core-0.11.0/lib/padrino-core/mounter.rb:231:in `new'
/var/lib/gems/1.9.1/gems/padrino-core-0.11.0/lib/padrino-core/mounter.rb:231:in `mount'
/home///config/apps.rb:36:in `'


config/apps.rbの36行目あたりが変わっているので、ジェネレータに合わせて修正します。

# 削除
- Padrino.mount("RingoTabeta").to('/')
- Padrino.mount("Admin").to("/admin")
- Padrino.mount("::Admin", :app_file => File.expand_path('../../admin/app.rb', __FILE__)).to("/admin")

# 追加
+ Padrino.mount('RingoTabeta::App', :app_file => Padrino.root('app/app.rb')).to('/')
+ Padrino.mount("RingoTabeta::Admin", :app_file => File.expand_path('../../admin/app.rb', __FILE__)).to("/admin")
app/controllers配下、app/helpers配下の修正

再度bundle exec rake db:migrateすると、またエラーが変わります。

rake aborted!
undefined method `helpers' for RingoTabeta:Module
/home///app/helpers/apples_helper.rb:5:in `'


app/app.rbを修正したことにより、モジュール名とクラス名が変わっているので、そちらを修正する必要があります。
helpers/apples_helper.rb

- RingoTabeta.helpers do
+ RingoTabeta::App.helpers do


controllers/apples.rb

- RingoTabeta.controllers :apples do
+ RingoTabeta::App.controllers :apples do
admin/controllers配下の修正

再度bundle exec rake db:migrateをすると、またエラーが変わります。

uninitialized constant Admin
/home///admin/controllers/tweets.rb:1:in `'


admin/app.rbを修正したことによる影響のため、admin/controller配下を修正します(いずれも先頭行あたり)。

admin/controllers/accounts.rb

- ::Admin.controllers :accounts do
+ RingoTabeta::Admin.controllers :accounts do


admin/controllers/apples.rb

- Admin.controllers :apples do
+ RingoTabeta::Admin.controllers :apples do


admin/controllers/base.rb

- ::Admin.controllers :base do
+ RingoTabeta::Admin.controllers :base do


admin/controllers/sessions.rb

- ::Admin.controllers :sessions do
+ RingoTabeta::Admin.controllers :sessions do


admin/controllers/tweets.rb

- Admin.controllers :tweets do
+ RingoTabeta::Admin.controllers :tweets do
初期データの投入

以上で必要な修正を終えたため、マイグレーションと初期データの投入を行います。

bundle exec rake db:migrate

bundle exec rake db:seed
Adminページのモデル表示の修正

先ほど再生成したAdminページには、ApplesとTweetsのモデルが表示されなくなっているため、再度ジェネレーターで生成します。
なお、conflictした場合は、すべて「y」にします。

padrino g admin_page apple

padrino g admin_page tweet


以上により、0.11.0対応は完了です。



■確認

以下へとアクセスし、正常に動作することを確認します。

  • localhost:3000
  • localhost:3000/admin

■Herokuへのアップ

git add .
git commit
heroku login
git push heroku master


以上で、対応は完了です。
PostgreSQLのインストールだけですまそうと思いましたが、結果的にPadrino0.11.0対応も同時にできたのが良かったです。
Padrino0.11.0へのアップデートに関する情報は、他にも以下のようなことがあるようです。
Ruby - Upgraded to Padrino 0.11.0 - Qiita



■ソース

GitHubに上げてあります。
thinkAmi/ringo-tabetter · GitHub