RailsによるアジャイルWebアプリケーション開発第二版を勉強するの巻(第2回:5章〜6章の途中まで)
これは何?
RailsによるアジャイルWebアプリケーション開発 第2版
- 作者: Dave Thomas,David Heinemeier Hansson,Leon Breedt,Mike Clark,Andreas Schwarz,James Duncan Davidson,Justin Gehtland,前田修吾
- 出版社/メーカー: オーム社
- 発売日: 2007/10/26
- メディア: 大型本
- 購入: 18人 クリック: 300回
- この商品を含むブログ (134件) を見る
分厚い上、27章まであるので、数回に分けて書きます
目次
はじめに
Instant Rails2.0を使って作業をしていたため、デフォルトでは、Railsのバージョンが2.0.2であったことが判明
本では、Rails1.2をベースにかかれており、Rails2.0だと挙動が異なるscaffoldのあたりでハマる事件が発生
後、Rails2.0だと、SQLiteがデフォルトのDBなのね…
C:\InstantRails-2.0-win\rails_apps>rails --version Rails 2.0.2
Railsのそれぞれのバージョンがインストールされているなら、以下の方法で、1.2.6版のRailsアプリを作る事も出来るらしい
バージョンを指定してRailsアプリケーションを作る | JAM☆ぱん
現状windows環境なので、泣く泣くInsant Rails 1.7をダウンロード(回線細いので時間かかる…)
C:\InstantRails-1.7-win\InstantRails\rails_apps>rails --version Rails 1.2.3
今度こそおっけー
5章 Depotアプリケーション
ショッピングカートをインクリメンタルに作りながら、Railsを学ぼう的な内容
基本仕様と、ざっくりしたページフローとか
6章 タスクA:商品の管理
イテレーションA1:動くものを作る
- Railsアプリを作る
C:\InstantRails-1.7-win\InstantRails\rails_apps>rails depot
- MySQLでDBを作る
C:\InstantRails-1.7-win\InstantRails\rails_apps>mysqladmin -u root create depot_development
./depot/config/database.yml に、上記DBの設定が入る
# コメントはかせいさん注 # 開発用DBの設定 development: # 使用中のDBの種類 adapter: mysql # データベースの名前(上で設定した奴) database: depot_development # ユーザ名 username: root # パスワード password: # DBを実行しているマシンのアドレス host: localhost # テスト用DBの設定 test: … # 本番用DBの設定 production: …
んで、DBがRailsと紐付いてるか確認
C:\InstantRails-1.7-win\InstantRails\rails_apps>rake db:migrate rake aborted! No Rakefile found (looking for: rakefile, Rakefile, rakefile.rb, Rakefile.rb) C:/InstantRails-1.7-win/InstantRails/ruby/lib/ruby/gems/1.8/gems/rake-0.7.2/lib/rake.rb:1849:in `load_rakefile' (See full trace by running task with --trace)
なんか失敗!
色々調べてみたら、単にアプリのあるディレクトリで実行してないだけでした…。
参考:Ruby (T3) # rake aborted! No Rakefile found
改めて、確認
C:\InstantRails-1.7-win\InstantRails\rails_apps\depot>rake db:migrate (in C:/InstantRails-1.7-win/InstantRails/rails_apps/depot)
なんか上手く行った様子
本には、上手くいなかった場合の解決法がいろいろ書いてあるけど、一番うっかりやらかしそうなこの解説は無かった…
Productsモデルとテーブルの作成
データベースマイグレーション
- データベースの変更の履歴を残しつつ、比較的手軽にDBの内容を設定できる
まずはやってみる
C:\InstantRails-1.7-win\InstantRails\rails_apps\depot>ruby script/generate model product exists app/models/ exists test/unit/ exists test/fixtures/ create app/models/product.rb create test/unit/product_test.rb create test/fixtures/products.yml create db/migrate create db/migrate/001_create_products.rb
001_create_products.rbが、マイグレーションファイル
class CreateProducts < ActiveRecord::Migration def self.up create_table :products do |t| end end def self.down drop_table :products end end
upメソッドに、このマイグレーションを適用した時の処理を書く
downは、ロールバックした時用
デフォルトで、products テーブルの生成と削除が書かれている
ここのupメソッドにて、テーブルのカラムを定義する
class CreateProducts < ActiveRecord::Migration def self.up create_table :products do |t| t.column :title, :string t.column :description, :text t.column :image_url, :string end end def self.down drop_table :products end end
入力した内容をRakeに実行させてテーブルを作らせてみる
- Rakeがまだ適用していないマイグレーションを全て実行してくれるらしい
C:\InstantRails-1.7-win\InstantRails\rails_apps\depot>rake db:migrate (in C:/InstantRails-1.7-win/InstantRails/rails_apps/depot) == CreateProducts: migrating ================================================== -- create_table(:products) -> 0.2040s == CreateProducts: migrated (0.2040s) =========================================
DBを見てみる
C:\InstantRails-1.7-win\InstantRails\rails_apps\depot>mysql -u root depot_development Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 4 to server version: 5.0.27-community Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> SHOW TABLES; +-----------------------------+ | Tables_in_depot_development | +-----------------------------+ | products | | schema_info | +-----------------------------+
きちんと、products テーブルができている
- schema_infoは、マイグレーションのバージョンを保存しているテーブルでRakeが勝手に作るらしい
products のテーブル定義
mysql> show fields from products; +-------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | title | varchar(255) | YES | | NULL | | | description | text | YES | | NULL | | | image_url | varchar(255) | YES | | NULL | | +-------------+--------------+------+-----+---------+----------------+
ちゃんと作られているっぽい!
ついでにschema_infoの中身
mysql> select * from schema_info; +---------+ | version | +---------+ | 1 | +---------+
バージョンだけ。シンプル
- 関係ないけど、show fields schema_info; ってやったらエラーがでて怒られた。何でだろ?
コントローラの作成
adminという名前のコントローラを作ってみる
C:\InstantRails-1.7-win\InstantRails\rails_apps\depot>ruby script/generate controller admin exists app/controllers/ exists app/helpers/ create app/views/admin exists test/functional/ create app/controllers/admin_controller.rb create test/functional/admin_controller_test.rb create app/helpers/admin_helper.rb
./depot/app/controllers に admin_controller.rb が生成される
なかみはこんだけ
class AdminController < ApplicationController end
管理アプリケーションの追加
ここに、scaffold :productを追加
class AdminController < ApplicationController scaffold :product end
Railsを起動して、http://localhost:3000/admin にアクセスしてみる
おおお、うまくいった!
New productから、新規にデータを入れてみる
うまく入った様子
Railsのscaffold
「足場」の意味
モデルを操作する為のフレームワークで、ジェネレータによって自動生成される
対象にしたテーブル(今回ならproduct)の中身を見て、いい感じに表示、入力用のHTMLを生成してくれる
大抵、アプリの開発が進むにしたがって、scaffoldは消えてなくなる
テスト用にデータを入力、表示したい時や、開発者用の外部に出さない部分等に使う感じらしい
イテレーションA2:足りない列の追加
productに、価格(price)列を追加する
新しいマイグレーションの生成
C:\InstantRails-1.7-win\InstantRails\rails_apps\depot>ruby script/generate migration add_price
exists db/migrate
create db/migrate/002_add_price.rb
002_add_price.rb が生成されるので、中にprice追加の処理を追記する
class AddPrice < ActiveRecord::Migration def self.up # 列追加 # precision :値の有効桁数 # scale :有効桁数の内、小数点の桁数 # default :デフォルト値 add_column :products, :price, :decimal, :precision => 8, :scale =>2, :default => 0 end def self.down # 列削除 remove_column :products, :price end end
んで、マイグレーションの実行
C:\InstantRails-1.7-win\InstantRails\rails_apps\depot>rake db:migrate (in C:/InstantRails-1.7-win/InstantRails/rails_apps/depot) == AddPrice: migrating ======================================================== -- add_column(:products, :price, :decimal, {:precision=>8, :scale=>2, :default=>0}) -> 0.2340s == AddPrice: migrated (0.2340s) ===============================================
もっかい、http://localhost:3000/admin にアクセスしてみる
priceが追加されてる!
Railsの再起動なしにこれはすごい!
イテレーションA3:検証!
入力内容をチェックする処理を追加する
モデル層にて、入力した内容をDBに格納する前にチェックを行う
具体的には、./depot/app/models/product.rb に追記する
class Product < ActiveRecord::Base # 必須チェック validates_presence_of :title, :description, :image_url # 数値以外エラー validates_numericality_of :price # ユニークであること validates_uniqueness_of :title # 正規表現でフォーマットをチェック validates_format_of :image_url, :with => %r{\.(gif|jpg|png)$}i, :message => "は、GIF,JPG,PNGのURLでなければなりません" # 自作のバリデータ # (validate内に記述する) private def validate # errors.addで、バリデート時のエラーメッセージを表示 errors.add( :price, "は、0.01以上の値である必要があります") if price.nil? || price < 0.01 end end
そうすると、こんな感じに入力チェックをするようになる
今日はここまで、イテレーションA4の静的なscaffoldに続きます
そんな感じー