第?部 アプリケーションを構築する
第9章 タスクD:チェックアウト!
ふう。できたバイ。
この章ではDRYなコードにするためにRailsがどんだけ手段を提供してるのかっていうところを感じることができた。
ところで、前章のショッピングカートの中身を一覧表示する画面で不具合がある。
カートにある商品を入れて、その状態で商品の単価を変更する。
そんでまた商品を追加して、カートの一覧をみると、単価は最初にカートにいれたときの単価が表示されるけど、合計金額は変更後の単価も反映される。
qty product unit_price unit_price*qty
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
一覧表示するときに、最新の単価を検索する必要があると思う。
あとで余裕があったらなおしてみる。
さて、第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アプリケーション開発 | |
前田 修吾 オーム社 2006-02-25 売り上げランキング : Amazonで詳しく見る by G-Tools |