先日買った本を読んでいるわけですが、まとめておかないとすぐ忘れるのでメモメモ*1。
何も知らない人が呼んでもチンプンカンプンだと思いますが、一度Railsを使ったことのある人なら記憶を呼び起こすに十分だと思いますよ。
○準備
1:rails XXXXコマンドで大枠を作成
2:データベースをDBサーバ上に必要なだけ用意(開発用、テスト用、本番用を用意しておくとよい)
3:SQLファイルを用意(idというカラムを各テーブルに用意すること)
4:config/database.ymlにデータベースの情報を書き込む(文字コードの設定も忘れずに)
○商品管理ページの作成
1:ruby script/generate scaffold Product(モデル名) Admin(コントローラ名)
で管理アプリケーションの雛形を自動生成
※本来やるはずのruby script/generate model XXXXXというようなモデルの生成は勝手に行われてるみたい
※データベースのテーブル名はモデル名+s(複数形)となる
2:app/models/モデル名.rbにバリデーションをする必要があればその処理を書き込む
validates_presence_of,validates_numericality_ofメソッドとか使うとよろし
○商品カタログページの作成
1:ruby script/generate scaffold Store(モデル名) index(コントローラ名)
でカタログページの雛形を自動生成
2:モデルのindex(コントローラ名)メソッドにデータベースから適切なデータを取り出してビューに渡すコードを書く。DBにアクセスするためのfind()メソッドとか使うとよろし
3:渡されたデータを使って適切なHTMlを吐くapp/views/store/index(コントローラ名).rhtmlを書く
4:レイアウトをキレイにする
/app/views/layoutsディレクトリのコントローラ名と同じ名前のファイルを編集するとそれがそのコントローラで生成されるページ全てに適用される
※<%= content_for_layout %>のところにビューで生成されたものが入る
○カートページの作成
1:Cookieを使う必要があればsessionマップを使って自分で永続状態を管理できるようにする
2:データベース(今まで使ってきたやつ)に商品購入情報のテーブルを追加
3:ruby script/generate model LineItem
とかでモデルを生成
※クラス名がLineItemとかだとテーブル名はline_itemになる
※外部キーの関係が過去のテーブルとにあるならbelongs_to :XXXXというのをモデルのクラスに書き込む
4:add_to_cartというようなアクションを作成するために、Storeコントローラにadd_to_cartメソッドを作成
5:カートに対応するようなクラスをapp/modelsディレクトリ内に作成。
※DBと直接マップされるわけではないのでActiveRecord::Baseのサブクラスにはしない
6:カートを表示するようなdisplay_cartメソッドとそれに対応するviewを作成
7:app/controllers/application.rbにmodel: xxxというようにモデルの宣言をする
(ver 0.13.1以降は必要ないらし)
8:各ビューで使いたいメソッドはapp/helper/XXX(コントローラ名)helper.rbの中に書く
○チェックアウト
1:入力フォームをビューに作る
<%=start_form_tag(action=>"XXXXX")%>
<%=text_fielsd("XXXX(モデル名)","YYYYY(カラム名)","size"=>40(フォームのサイズ))%>
<%= end_form_tag %>
とかすれば入力フォームができる。そこにはモデルの値が設定されている。
※実際にはstrt〜endの間にHTMLタグも入る
2:@order = Order.new(paramas[:order])
という感じでフォームに入力された情報からモデルオブジェクトを生成
@order.save
でDBへ書き込み
※モデルの保存時の検証で生成されたエラーメッセージは
<%= error_message_for("order")%>で取得可能
○さらにイテレーション
1:他のビューの出力を取り込みたい時は
<%=render_component(:action =>"XXXXX"%)
とすればOK。
そのまま挿入されて困る時は
<%=render_component(:action =>"XXXXX",:params => {:context => :checkout})%>
とでもしてアクションにパラメータを渡してそれによって表示を変えさせればOK
受け取る側は
params[:context]
として受け取る。
2:ビューを複数に分ける<%=render(:partial -> "XXXXXX(部分の名前)",:collection -> @YYYYYY(イテレイタブルな変数?))>
でアンダーバーをつけた_XXXXX.rhtmlが挿入される
3:スタイルシートを使いたい<%= stylesheet_link_tag "XXXX","YYYY"・・・・(CSSファイル名を列挙していく),:media=>"all">%>
と挿入
4:単独で入力フォームを使いたい時(DBのテーブルに対応したオブジェクトに直接マップしたりしない時)<%= check_box("XXXX",YYYYY(可変の文字列変数),{},"yes","no")%>
とかすると
@params = {"XXXXXX"={"YYYYYY" => "入力された値"}}
といった感じで所得できる
5:POSTかGETか知りたい
コントローラでrequest.get?とすることで分かる
6:アクセス制限をかけたい
フィルタを使えばよろし。
具体的にはbeforeとか。
任app/controllers/application.rb
とかに
before_filter :arthorize
def authorize
ログイン状態か検証するメソッドの中身
end
と書き込めばOK
※あるアクションは例外としたいという時はbefore_filter :arthorize,:expect=>:XXX(アクション名)というように宣言しておく
7:ドキュメントを生成したい
rake appdoc
とコマンドを打つ
○テストをする(準備)
1:テスト専用のデータベースのセットアップ。
rake clone_structure_to_test
とすればSQLをテスト用のデータベースに適用しなくても自動的にスキーマがコピーされる(構造だけね)(Rakeでテストを実行する場合は自動的にこのコマンドが呼ばれるらし)
2:テスト用の初期データ(フィクスチャ)を用意する
test/fixturesディレクトリにテーブル名.ymlというYAMLファイルを用意
書き方はエントリを列挙する感じ
XXXXXX(エントリ名1):
カラム名 : 値
・
・
カラム名が続く
XXXXXX(エントリ名2):
カラム名 : 値
・
・
カラム名が続く
※外部参照がある時はもっとややこしい
○テストをする(モデルのテスト)
1:XXXXTestクラスに
fixtures :XXXXX(フィクスチャ名)
と書いてあることを確認。これはフィクスチャをDBにロードするメソッド
2:XXXXTestクラスにテストメソッドを追加
具体的には
assert_kind_of YYYYYY(モデル名),@YYYYY
assert_equal "フィクスチャからロードしていたら一致するはずの値",検証したい変数
ってなものを使ってテストメソッドを構成
ここで"フィクスチャからロードしていたら一致するはずの値"を得るために
フィクスチャのエントリ名がインスタンス変数として自動的に用意されるので
test_entry.id,YYYY(モデル名).id
みたいな感じで書ける。
3':自作のアサーションを使いたいたい
test_helper.rbに自作のアサーションメソッドを定義すればよし
○テストをする(コントローラのテスト)
1:XXXXTestクラスにテストメソッドを追加
例えば
get :YYYY
でYYYYアクションに対するGETリクエストを行って
assert_response :success
でそのリクエストが成功したかチェックできる。
assert_redirect_to :action => "ZZZZZ"
とすればZZZZZにリダイレクトされたかチェックできる
post :login(アクション名), :user => {:name => 'fred',:password => 'opensesami'}
とかでPOSTリクエストもできる
2:モックオブジェクトが使いたい場合は
test/mocks/test/
に"クラス名と同じ名前を単語の区切りを_(アンダーバー)で区切った名前".rbとしておいておけばよい
○テストをまとめてやる
プロジェクトのルートパスで
rake
を実行。
rake test_units
だとモデルのテストだけ
rake test_fuctional
だとコントローラのテストだけ
rake recent
とすれば変更を加えたテストだけ行う
rake stats
とするとテストに関する統計情報が得られる
○プロファイリング
もできるよ。
*1:今読んでる本は良書だと思うのだが、手順をパッと見てわからないのがなんなのよね