Railsによるアジャイル〜 rail2.0版 イテレーションA1

 「RailsによるアジャイルWebアプリケーション開発」第2版にそってrails2.0でやってみる。6章のチュートリアルから。
 ちなみに、rails2.0の参考したのは、http://api.rubyonrails.org/

6.1 イテレーション A1:動くものを作る

railsアプリケーションの作成

問題無し。

データベースの設定

ここから早速違う。rails2.0からはMySQLではなく、SQLiteが標準となったので、こちらを使うようにする。といっても、設定は何もいらない。むしろ本に書いているデータベースの作成は不要。

アプリケーションの設定

ここで示しているconfig/database.ymlが、以下のようになる。

# rails2.0対応版
development:
  adapter: sqlite3
  database: db/development.sqlite3
  timeout: 5000
設定のテスト

rakeは同じ。SQLiteでのデータベースの確認方法は以下。

depot> sqlite3 db/developmenet.sqlite3
SQLite version 3.5.6
Enter ".help" for instructions
sqlite> .q
Productsモデルとテーブルの作成

本の例でもいいが、rails2.0になってから、テーブル定義をより簡潔に書けるようになった。タイプを指定して、複数カラムを同時に作成したりもできる。テーブル定義の例。

  create_table :products do |t|
    t.string :title, :image_url
    t.text   :description
    t.timestamps
  end

ジェネレーターが作ったテンプレートにはtimestampsが追加されるようになったので、せっかくので使ってみる。

コントローラの作成

同じ。

管理アプリケーションの作成

Controllerでscaffoldを使用しているのだが、rails2.0になってscaffoldが大きく変わって、このままでは動かない。ここではまる人は多いようで、先人の知恵を拝借。

 端的に言うと、rails2.0からは動的なscaffoldは外部プラグインになったので、手動でプラグインのインストールが必要。さらにscaffoldが依存するpaginateやwill_paginateも必要と。
pluginのインストールについては別エントリpluginのインストールとかを参照。

 また、rails2.0からはデフォルトでCSFR対策がされるようになったそうで、その設定行わないとサンプルアプリのデータ更新で InvalidAuthenticityToken エラーが発生する。とりあえずは、無効にしておけばいいんじゃかな。コントローラの元となる ApplicationController(app/controllers/application.rb)で、protect_from_forgeryの呼び出しがあるので、そこをコメントアウトする。

class ApplicationController < ActionController::Base
  helper :all # include all helpers, all the time

  # この下をコメントアウトする
  #protect_from_forgery # :secret => 'dce30641d609069ec190e2dd310a6d24'
end

 アプリケーション全体で無効にする場合は、config/environments/test.rbに以下を追記。

Rails::Initializer.run do |config|
  ...
  config.action_controller.allow_forgery_protection = false
  ...
end

RailsでのCSFR対策については以下を参照

 簡単に言うと、protect_from_forgery が書かれていると、自動的にフォーム中にhiddenのauthenticity_tokenというパラメータが作成され、POST時に正しいトークンじゃないとエラーにする、といったことらしい。scaffoldで動的に作成した場合は、このhiddenパラメータが自動的に作られないため、エラーになってしまう(のだと思う。。)

 色々調べてみると、コントローラに以下のように書くと動いた、等あるが

  protect_from_forgery :secret => 'hogehoge', :only => :index

動くのは当たり前で、only で index を指定してるため、indexアクション時にだけが対象になり、しかも通常indexアクションはPOSTじゃないので、結局、無効にしてるのと実質同じ。

次回は、6.3 イテレーション A2:足りない列の追加