第?部 アプリケーションを構築する

第9章 タスクD:チェックアウト!

ふう。できたバイ。
この章ではDRYなコードにするためにRailsがどんだけ手段を提供してるのかっていうところを感じることができた。


ところで、前章のショッピングカートの中身を一覧表示する画面で不具合がある。
カートにある商品を入れて、その状態で商品の単価を変更する。
そんでまた商品を追加して、カートの一覧をみると、単価は最初にカートにいれたときの単価が表示されるけど、合計金額は変更後の単価も反映される。

qty product  unit_price  unit_price*qty
                                                                          • -
2 りんご $200.00 $400.00 total: $410.00

一覧表示するときに、最新の単価を検索する必要があると思う。
あとで余裕があったらなおしてみる。


さて、第9章ではチェックアウト!ってことで、注文を確定して発注データをつくるとこまでやる。
まずは発注データを格納するordersテーブルを作成する。
このordersテーブルは顧客の名前、メールアドレス、決済手段などを格納するテーブル。
発注する商品の情報は関連テーブルのline_itemsテーブル(カートの中のデータを持ったモデル)に格納する。
orders:line_items = 1 : n。
ヘッダ・ディティール関係です。


ordersテーブルのモデルはこうなる

class Order < ActiveRecord::Base
  has_many :line_items
end


line_itemsテーブルのモデルはこうなる

class LineItem < ActiveRecord::Base
  belongs_to :product
  belongs_to :order
  ・・・
end


このあたりの書き方って気を使ってるんやなあ・・

フォーム

さて、ordersテーブルに入れる顧客データをPOSTするフォーム。
JSPのタグリブみたいに動的にHTMLを作成するスクリプトレット(?)が書けます。
これはビューで使える自動でincludeされるメソッドですね。
ビューヘルパー。

<%= start_form_tag(:action => "save_order" %>
・・・
<%= submit_tag("チェックアウト") %>
・・・
<%= end_form_tag %>

便利ですね。

フォーム内のオブジェクト

inputタグとかは

<%= text_field("order", "name", :size => 40) %>

こんなビューヘルパーを使います。
これはHTMLに展開されるとこんなことになります。

<input id="order_name" name="order[name]" size="40" type="text" value="" />

どうなってるかというと、@orderモデルのnameフィールドが設定されるということです。
これをsubmitしたときはコントローラーで

@order = Order.new(params[:order])

こういう感じで受け取ることができます。
 

validate

scaffoldで作成したモデルにvalidatesメソッドを記述したときは
エラーメッセージが画面にばっちり出るわけですが、自前でmodelつくってvalidatesメソッドを書いてview書いたときはエラーメッセージを表示するために、viewに

<%= error_messages_for("order") %>

と書いときます。
エラーはモデルで保持しているのでこれでおけ。

ビューの使いまわし

この章で一番おもしろいのはここですかね。
チェックアウト画面の中でカート内容一覧画面をincludeして表示します。
それをやるためにはチェックアウト画面のビューで

<%= render_component(:action => "display_cart") %>

と書いておく。そうすっとビューのdisplay_cart.rhtmlが展開されるわけです。
こういう使いまわしをRailsコンポーネントシステムというらしい。

が、レイアウトを使ってる場合はレイアウトも一緒に展開されてしまいます。
ここではdisplay_cart.rhtmlのレイアウトを表示したくないわけです。
レイアウトを除いて展開するためにはさっきのビューヘルパーを

<%= render_component(:action => "display_cart",
                     :params => { :context => :checkout }) %>

こういう風に変更して、display_cartメソッドにパラメータを渡すようにして、
display_cartメソッドで

def display_cart
 ・・・
 if params[:context] == :checkout
   render(:layout => false)
  end
end

こんな条件分岐をいれておく。これで桶です。



RailsによるアジャイルWebアプリケーション開発
RailsによるアジャイルWebアプリケーション開発前田 修吾

オーム社 2006-02-25
売り上げランキング :


Amazonで詳しく見る
by G-Tools