Ruby on Rails ショッピングカート part7 発送

Ruby on Rails において ショッピングカート とは以下を示します。

  1. メソッド追加
     Orderクラスから「shipped_at列がnull」の行を取得するメソッドを
     追加する。
    
    1. /app/controllers/admin_controller.rb
       def ship
         @pending_orders = Order.pending_shipping
       end
      
  2. クラスメソッド追加
     上記のクラスメソッドを追加する。
    
    1. /app/models/order.rb
       def self.pending_shipping
         find(:all, :conditions => "shipped_at is null")
       end
      
  3. ビュー作成
     ビューを作成しますが、このビューには各注文の表示欄にチェック
     ボックスを表示するため、フォームを使用して、①フォームを表示
     する部分、②各注文を表示する部分、に分割して、コードを明瞭化する。
    
    • チェックボックス
        <%= check_box("to_be_shipped", order_line.id, {}, "yes", "no") %>
        最初のパラメータは、フィールドの名前に使用される。
        2つ目のパラメータは、フィールドの名前 to_be_shipped[1] の
        ように使用される。最後の3つのパラメータは、オプション(この
        場合は空)、オンの状態の時の値、オフの状態の時の値。
      
    1. /app/views/admin/ship.rhtml
       <h1>未発送の注文</h1>
      
       <%= form_tag(:action => "ship") %>
      
       <table cellpadding="5" cellspacing="0">
       <%= render(:partial => "order_line", :collection => @pending_orders) %>
       </table>
      
       <br />
       <input type="submit" value=" チェックマークが付いている注文の商品を発送する " />
      
       <%= end_form_tag %>
       <br />
      
    2. /app/views/admin/_order_line.rhtml
       <tr valign="top">
      
         <td class="olnamebox">
           <div class="olname"><%= h(order_line.name) %></div>
           <div 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>
      
  4. 画面表示
     表示してみた!!
    
    • http://www.bishounen.sakura.ne.jp/rails/images/knowledge/150_01_ship.jpg
  5. 管理画面のレイアウトを修正
     管理画面はなんか見難い。だから、レイアウトを修正したい。
    
    1. /app/views/layouts/admin.rhtml
       <html>
         <head>
           <title>Pragprog Books オンラインストアの管理</title>
           <%= stylesheet_link_tag "scaffold", "depot", "admin", :media => "all" %>
         </head>
         <body>
           <div id="banner">
             <%= @page_title || "書籍の管理" %>
           </div>
           <div id="columns">
             <div id="side">
               <%= link_to("商品リスト",   :action => "list") %><br />
               <%= link_to("発送",   :action => "ship") %>
             </div>
      
             <div id="main">
               <% if flash[:notice] -%>
                 <div id="notice"><%= flash[:notice] %></div>
               <% end -%>
               <%= @content_for_layout %>
             </div>
           </div>
         </body>
       </html>
      
  6. 画面表示
     list画面、ship画面はそれぞれこんな風に。
    
    • http://www.bishounen.sakura.ne.jp/rails/images/knowledge/150_02_list.jpg
    • http://www.bishounen.sakura.ne.jp/rails/images/knowledge/150_03_ship.jpg
  7. スタイルシート追加
     adminスタイルシートを作成してみる。
    
    1. /public/stylesheets/admin.css
       /* order shipping screen */
      
       .olheader {
         font: bold large sans-serif;
         color: #411;
         margin-bottom: 2ex;
       }
      
       .olnamebox, .olitembox {
         padding-bottom: 3ex;
         padding-right: 3em;
         border-top: 1px dotted #411;
       }
      
       .olname {
         font-weight: bold;
       }
      
       .oladdress {
         font-size: smaller;
         white-space: pre;
       }
      
       .olitemqty {
         font-size: smaller;
         font-weight: bold;
       }
      
       .olitemqty:after {
         content: " x ";
       }
      
       .olitemtitle {
         font-weight: bold;
       }
      
  8. 画面表示
     ship画面はこんな風に。
    
    • http://www.bishounen.sakura.ne.jp/rails/images/knowledge/150_04_ship_add_style.jpg
  9. チェックボックスの内容
     このshipフォームのデータを送信すると、Railsは解析時に
     「フィールド名にインデックスが付与されている」ことを検出して処理する。
     すなわち、フィールド名を分割して、to_be_shippedの部分はハッシュを示す
     パラメータをして扱い、インデックス(id)をキーにして、value(yesとかno)を
     格納する。
    
    • idが1の注文のチェックボックスがオンの状態の場合
        @params = { "to_be_shipped" => { "1" => "yes" } }
      
    • だから、こんな感じの処理をイメージ
        to_ship = params[:to_be_shipped]
        if to_ship
          to_ship.each do |order_line, do_it|
            if do_it == "yes"
              # 発送処理
            end
          end
        end
      
    • 参考
        ここでの発送処理は要件によって異なる。
        商品が品切れで発送を待っている、同じ商品はまとめて発送したい、
        とか色々な要件がある。
      
        だから、ここでは発送する商品にチェックを行うことにする。
        また、その作業を行う人は1人とし、複数人数による同時作業は想定しない。
        ・・・・・同時に同じ商品を発送したら、ユーザーはお得?それとも逆に邪魔?
      
  10. メソッドを編集、クラスメソッドも追加
     このチェックボックスのオン、オフをデータベースに登録する機能を追加する。
    
    1. /app/controllers/admin_controller.rb
       def ship
         count = 0
         if things_to_ship = params[:to_be_shipped]
           count = do_shipping(things_to_ship)
           if count > 0
             flash.now[:notice] = "#{count} 件の注文が発送済みとしてマークされました"
           end
         end
         @pending_orders = Order.pending_shipping
       end
      
       private
      
       def do_shipping(things_to_ship)
         count = 0
         things_to_ship.each do |order_id, do_it|
           if do_it == "yes"
             order = Order.find(order_id)
             order.mark_as_shipped
             order.save
             count += 1
           end
         end
         count
       end
      
    2. /app/models/order.rb
       def mark_as_shipped
         self.shipped_at = Time.now
       end
      
  11. 商品発送
     チェックボックスをオンにして発送!!
    
    • http://www.bishounen.sakura.ne.jp/rails/images/knowledge/150_05_db_ship.jpg
     データベースもshipped_atが変更されている。
    
    • http://www.bishounen.sakura.ne.jp/rails/images/knowledge/150_06_db_orders.jpg
    1. /log/production.log
       Processing AdminController#ship
       (for 124.102.28.37 at 2007-02-08 17:44:36) [POST]
         Session ID: 14b8ef7c4be61526eaa7cbe662c603a5
         Parameters: {"action"=>"ship",
                      "controller"=>"admin",
                      "to_be_shipped"=>{"1"=>"no", "2"=>"yes"}}
       Rendering  within layouts/admin
       Rendering admin/ship
       Completed in 0.16164 (6 reqs/sec) |
       Rendering: 0.01154 (7%) | DB: 0.07384 (45%) |
       200 OK [http://www.bishounen.sakura.ne.jp/rails_depot/admin/ship]
      
  12. 商品発送(補足)
     以前に作成した不正データは削除できない!!・・・・・なぜ??
     ログは"OK"なのにDBは変更されない。
    
    1. /log/production.log
       Processing AdminController#ship
       (for 124.102.28.37 at 2007-02-08 17:45:52) [POST]
         Session ID: 14b8ef7c4be61526eaa7cbe662c603a5
         Parameters: {"action"=>"ship",
                      "controller"=>"admin",
                      "to_be_shipped"=>{"1"=>"yes"}}
       Rendering  within layouts/admin
       Rendering admin/ship
       Completed in 0.10763 (9 reqs/sec) |
       Rendering: 0.01393 (12%) | DB: 0.05345 (49%) |
       200 OK [http://www.bishounen.sakura.ne.jp/rails_depot/admin/ship]
      
       [結論]直接DBのデータを変更したら、発送できた。
      
    • http://www.bishounen.sakura.ne.jp/rails/images/knowledge/150_07_db_update_orders.jpg

ご訪問頂き有難う御座います。 当サイトを効率良く使うためにまずは FrontPage を見て下さい。 検索方法、一覧表示などの各情報を纏めています。
当サイトの説明 → Frontpage