Ruby on Rails ショッピングカート part4 不正URL
Ruby on Rails において ショッピングカート とは以下を示します。
- 不正URL
http://www.bishounen.sakura.ne.jp/rails_depot/ store/add_to_cart/wibble URLにパラメータを直接入力すると、予期せぬエラーが 投げられます。sakuraインターネットでは、画面にエラー 出力されませんが、ログは以下の場所に出力される。
- /log/server.log
Processing StoreController#add_to_cart (for 125.207.237.21 at 2007-02-07 17:49:13) [GET] Session ID: 95e37b1ee87839158725a23274bb2c6c Parameters: {"action"=>"add_to_cart", "id"=>"wibble", "controller"=>"store"} ActiveRecord::RecordNotFound (Couldn't find Product with ID=wibble): ・ ・ dispatch.cgi:10
- こんな時は・・・・・
エラーを放置しないで例外対策が必要。 Railsのlogger機能を使用しログに出力、 またユーザー用に画面に表示。
- /log/server.log
- Flash
エラー処理と通知に便利な機能である。 リクエスト処理の過程でオブジェクトを格納できる。 また、フラッシュに格納されたオブジェクトは、次の リクエスト処理まで保持しており、その後は自動的に 削除される。
- 例外処理を追加
例外をrescue節で補足する。
- /app/controllers/store_controller.rb
def add_to_cart product = Product.find(params[:id]) @cart = find_cart @cart.add_product(product) redirect_to(:action => 'display_cart') rescue logger.error("無効な商品 #{params[:id]} にアクセスしようとしました") flash[:notice] = '無効な商品です' redirect_to(:action => 'index') end
- /app/controllers/store_controller.rb
- 不正なパラメータを入力
http://www.bishounen.sakura.ne.jp/rails_depot/ store/add_to_cart/wibble しかし、ログファイルにエラーが記述され、リダイレクトで 以下の画面が出力さえる。
- ログ出力に関して
server.logのエンコードはsjisなので、utf-8に変換しないと 以下のようには出力されない。
- /log/server.log
Processing StoreController#add_to_cart (for 125.207.237.21 at 2007-02-07 18:18:25) [GET] Session ID: 58f973e38d9e41897cec4828d01ef4dd Parameters: {"action"=>"add_to_cart", "id"=>"wibble", "controller"=>"store"} 無効な商品 wibble にアクセスしようとしました Redirected to http://www.bishounen.sakura.ne.jp/rails_depot/store/index Completed in 0.05968 (16 reqs/sec) | DB: 0.00286 (4%) | 302 Found [http://www.bishounen.sakura.ne.jp/rails_depot/store/add_to_cart/wibble]
- ログ出力に関して
- エラー画面を作成
まだリダイレクトしただけで、エラー処理画面を表示していません。 このエラーは共通なので、レイアウト部分に書くことにする。 <% if @flash[:notice] -%> <div id="notice"><%= @flash[:notice] %></div> <% end -%>
- /app/views/layouts/store.rhtml
<html> <head> <title>Pragprog Books オンラインストア</title> <%= stylesheet_link_tag "depot", :media => "all" %> </head> <body> <div id="banner"> <img height="45" src="/rails_depot/rails/images/rails.png"/> <%= @page_title || "Pragmatic Bookshelf" %> </div> <div id="columns"> <div id="side"> <a href="http://www....">ホーム</a><br /> <a href="http://www..../faq">FAQ</a><br /> <a href="http://www..../news">ニュース</a><br /> <a href="http://www..../contact">お問い合わせ</a><br /> </div> <div id="main"> <% if @flash[:notice] -%> <div id="notice"><%= @flash[:notice] %></div> <% end -%> <%= @content_for_layout %> </div> </div> </body> </html>
- /app/views/layouts/store.rhtml
- レイアウトを追加
以下を追加する。
- /public/stylesheets/depot
#notice { border: 2px solid red; padding: 1em; margin-bottom: 2em; background-color: #f0f0f0; font: bold smaller sans-serif; }
- /public/stylesheets/depot
- display_cartも同様に
何もない状態で、カートを表示するのはおかしい。 http://www.bishounen.sakura.ne.jp/rails_depot/store/display_cart
- /app/controllers/store_controller.rb
def display_cart @cart = find_cart @items = @cart.items if @items.empty? flash[:notice] = '現在、カートには商品が入っていません' redirect_to(:action => 'index') end end
- チョット工夫
/app/views/layouts/store.rhtmlの <%= @page_title || "Pragmatic Bookshelf" %> 部分を工夫します。 display_cart.rhtmlの先頭に以下を追記する。 変数に文字を代入しているだけだけどね!!
- /app/views/store/display_cart.rhtml
<% @page_title = "現在のカートの内容" -%>
- /app/views/store/display_cart.rhtml
ご訪問頂き有難う御座います。
当サイトを効率良く使うためにまずは FrontPage を見て下さい。
検索方法、一覧表示などの各情報を纏めています。
当サイトの説明 → Frontpage