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

第10章 タスクE:発送

えーーー、発送ですね。商品の出荷です。
第9章までで、ユーザーが商品をチェックアウト(発注)するところまでできました。
この章では販売者が発送処理をするところをつくります。


ユーザーがチェックアウトしたところでorderテーブルにレコードが追加されています。
この本では発送したかどうかをorderテーブルのdatetime型の属性で判断してます。
発送してなければ、NULL。発送しているのは、発送した日時をセットします。


というわけで、未発送のレコードを取得するメソッドをOrderモデルに追加します。
こんな感じ。
app/models/order.rb

 def self.pending_shipping
   find(:all, :conditions => "shipped_at is null")
 end

:conditionsのとこがWHERE句の条件ですね。


コントロールに、未発送の一覧表示を呼び出すアクションを書きます。
app/controllers/admin_controller.rb

def ship
  @pending_orders = Order.pending_shipping
end


次に未発送のレコードを一覧表示するのですが、ここで部分テンプレートというものを使っています。
部分テンプレートは1つのビューの部分を切り出して別のビューをつくります。
これらの組み合わせで1つのビューを組み立てます。
似たようなことは第9章でやってます。
第9章でチェックアウト画面をつくるのに、別のアクションが呼び出すビューを使いまわしました。(コンポーネント)
部分テンプレートがコンポーネントと違う点は、部分テンプレートは対応するアクションを持ってないことです。
単純に1つのビューを分割して、組み合わせている、ということですね。
これが有効なところは、複雑なコードを別ファイルにできるところですかね。
繰り返し部分とか抜き出すとよいのかもしれない。
で、未発送の一覧表示ビューはこんな感じです。
app/views/admin/ship.rhtml

<h1>unshipped orders</h1>

<%= form_tag(:action => "ship") %>

<table cellpadding="5" cellspacing="0">
<%= render(:partial => "order_line", :collection => @pending_orders) %>
</table>

<br/>

<input type="submit" value="checked orders are shipping" />
<%= end_form_tag %>
<br/>


部分テンプレートを呼び出してるのは

<%= render(:partial => "order_line", :collection => @pending_orders) %>

のところですね。
:particalが指す値は2つの役割があります。
ひとつは部分テンプレートの名前を表します。
アンダーバーをつけて、_order_line.rhtmlになります。
もうひとつの役割はorder_lineという名前のローカル変数に繰り返してコレクションの要素をセットさせることです。
_order_line.rhtmlはコレクションがもっている要素の数だけ、繰り返して展開される!のです。
ウラでリフレクション。
というわけで、_order_line.rhtmlはこんな感じになります。
app/views/admin/_order_line.rhtml

<tr valign="top">
    <td class="olnamebox">
        <div class="olname"><%= h(order_line.name) %></div>
        <<iv class="oladdress"><%= h(order_line.address) %></div>
    </td>
    <td class="olitembox">
        <% order_line.line_items.each do |li| %>
        <div class="olitem">
            <span class="olitemqty"><%= li.quantity %></span>
            <span class="olitemtitle"><%= li.product.title %></span>
        </div>
        <% end %>
    </td>
    <td>
        <%= check_box("to_be_shipped", order_line.id, {}, "yes", "no") %>
    </td>
</tr>

order_lineにはpending_ordersが持っている要素の1つが割り当てられます。
というわけで、このビューはpending_ordersが持っている要素の数だけ繰り替えされます。
JSPのタグリブなんかと比べてコードを減らせるわけですね。
規約重視。


見栄えのことはとりあえず端折ります・・・
さて、この部分テンプレートの中でチェックボックスを表示するビューヘルパーを使ってます。
ここですね。

<%= check_box("to_be_shipped", order_line.id, {}, "yes", "no") %>

これがHTMLにレンダリングされるとこうなります。

<input name="to_be_shipped[1]" type="checkbox" value="yes" />
<input name="to_be_shipped[1]" type="hidden" value="no" />

to_be_shippedのあとについている番号は、order_line.idですね。
チェックボックスにチェックしてsubmitして渡されるパラメータはこんな感じになります。

@params = {"to_be_shipped" => {"1" => "yes"} }

これって、同じnameのオブジェクトが複数あったときに最初の値しかとれへんってこと?


ああーーー、ばててきた。
あと、フラッシュのスコープがリクエストになるflash.nowってのが出てきます。
このflash.nowの値はセッションには入らないんですと。
以前の章でflashを使ってたのはリダイレクトが絡んでたので、セッションに残るflashを使ってました。
別に今回のもflashでええと思うねんけど。


ところで!
どーーも、テーブルの属性が長さゼロの文字列がActiveRecordにうまくロードされへんみたいやけど
これって仕様??
ordersテーブルのnameとかに長さゼロの文字列が入ったレコードがあるんですけど、
このレコードをSELECTして、UPDATEするとこで
・SELECT文は実行されている。
・UPDATE文が実行されていない。
というのをログで確認したので。


だれかご存知でしたら教えてもらえないでしょうか。



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

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


Amazonで詳しく見る
by G-Tools