Top > Ruby on Railsあれこれ > 2-5 ショッピングカートを追加しよう

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <title>商品詳細</title>
</head>
<body>
  <table border="1">
    <thead>
      <tr>
        <th>商品番号</th>
        <th>商品名</th>
        <th>価格</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td><%=h @catalog.id %></td>
        <td><%=h @catalog.name %>&nbsp;<%=h @catalog.detail %></td>
        <td align="right"><%= number_with_delimiter(@catalog.price, delimiter=",") %></td>
      </tr>
      <tr>
        <td colspan="3"><%= image_tag(@catalog.pictureurl) %></td>
      </tr>
    </tbody>
  </table>
  
  <%# カートに入れるボタン(2-5で追加)%>
  <% form_tag({:controller => 'catalogs_order', :action => 'add'}) do %>
    <%# hidden_field_tagによる商品IDの引継ぎ %>
    <%= hidden_field_tag("id", @catalog.id) %>
    <%= submit_tag("この商品をカートに入れる") %>
  <% end %>
</body>
</html>

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
class CatalogsOrderController < ApplicationController
 
  #商品詳細画面の「この商品をカートに入れる」ボタンクリック時のアクション
  def add
    session[:cart] ||= Cart.new
    session[:cart].add(Catalog.find(params[:id]))
    @cart = session[:cart]
    render :action => 'cart.html.erb'
  end
  
  #「数量変更」ボタンクリック時のアクション
  def change 
    @cart = object_deep_copy(session[:cart])
    counts = params[:catalog]
    counts.each {|c|
      @cart.change(c[1]["id"], c[1]["count"])
    }
    #数量が0個の商品を削除します。
    @cart.compress
    
    #数量が有効値の場合のみセッションのカートに反映します。
    session[:cart] = @cart if @cart.valid?
    render :action => 'cart.html.erb'
  end
  
  #オブジェクトのディープコピーを行います。
  def object_deep_copy(obj)
    return Marshal.load(Marshal.dump(obj))
  end
  private :object_deep_copy
  
end

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
class Cart
  attr_reader :catalogs
  
  #コンストラクタ
  def initialize
    @catalogs = []
  end
  
  #カート内の各商品のバリデーションチェックを行います。
  def valid?
    valid = true
    @catalogs.each { |c|
      valid = false unless c.valid?
    }
    return valid
  end
  
  #カートに商品を追加します。既にカートに同一商品番号の商品がある場合は購入数に+1する
  def add(catalog)
    exist = false
    for c in @catalogs
      if c.id * catalog.id
        c.count = (c.count.to_i + 1).to_s
        exist = true
      end
    end
    if !exist
      catalog.count = "1"
      @catalogs << catalog
    end
  end
  
  #数量変更します。
  def change(id, count) 
    @catalogs.each { |c|
      if c.id * id.to_i
        c.count = count
        break
      end
    }
  end
  
  #カート内容の総合計金額を取得します。
  def getTotalPrice
    total = 0
    @catalogs.each { |c|
      total += c.price * c.count.to_i
    }
    return total
  end
  
  #カートから購入個数が0個の商品を削除します。
  def compress
    @catalogs.reject! {|c|
      c.count * "0"
    }
  end
end
  0
  1
  2
  3
  4
class Catalog < ActiveRecord::Base
  validates_presence_of :count, :message => "数値を入力して下さい。"
  validates_format_of :count, :with => /^[0-9]+$/, :message => "に数値を入力して下さい。", :if => proc{|catalog| !catalog.count.blank?}
  attr_accessor :count
end

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
<html>
<head>
  <title>ショッピングカートの内容</title>
  <%= stylesheet_link_tag 'ror' %>
</head>
<body>
購入予定のリストです。ご確認下さい。
<% @catalogs = @cart.catalogs %>
<%= list_error_messages_for "catalogs" %>
<% form_tag({:action => 'change'}) do %>
  <table border="1">
    <thead>
      <tr>
        <th>商品番号</th>
        <th>商品名</th>
        <th>価格</th>
        <th>数量</th>
        <th>小計</th>
      </tr>
    </thead>
    <tbody>
      <% for @catalog in @catalogs %>
      <tr>
        <td><%=h @catalog.id %></td>
        <td><%=h @catalog.name %>&nbsp;<%=h @catalog.detail %></td>
        <td align="right"><%= number_with_delimiter(@catalog.price, delimiter=",") %></td>
        <%# セッションに保存してあるカートの各商品の個数だけを書き換えるようにします %>
        <td><%= hidden_field("catalog[]", "id") %><%= text_field("catalog[]", "count") %></td>
        <td><%= number_with_delimiter(@catalog.price * @catalog.count.to_i, delimiter=",") %></td>
      </tr>
      <% end %>
    </tbody>
  </table>
  <br>
  <table border="1">
    <thead>
    </thead>
    <tbody>
      <tr>
        <td>合計</td>
        <td><%= number_with_delimiter(@cart.getTotalPrice, delimiter=",") %></td>
      </tr>
    </tbody>
  </table>
  <%# 複数商品の個数変更を一括して適用します %>
  <%= submit_tag "数量変更" %>
<% end %>
<br>
<%= link_to( "商品一覧へ戻る", {:controller => 'catalogs', :action => 'index'}) %>
</body>
</html>

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
@CHARSET "utf-8";
 
.formError {
  font-size: x-small;
  color: red;
  }
 
.fieldWithErrors {
  padding: 2px;
  background-color: red;
}
 
#errorExplanation {
  width: 400px;
  border: 2px solid red;
  padding: 7px;
  padding-bottom: 12px;
  margin-bottom: 20px;
  background-color: #f0f0f0;
}
 
#errorExplanation h2 {
  text-align: left;
  font-weight: bold;
  padding: 5px 5px 5px 15px;
  font-size: 12px;
  margin: -7px;
  background-color: #c00;
  color: #fff;
}
 
#errorExplanation p {
  color: #333;
  margin-bottom: 0;
  padding: 5px;
}
 
#errorExplanation ul li {
  font-size: 12px;
  list-style: square;
}

添付ファイル: fileror-sample2-5_6.jpg 393件 [詳細] fileror-sample2-5_5.jpg 362件 [詳細] fileror-sample2-5_4.jpg 406件 [詳細] fileror-sample2-5_3.jpg 381件 [詳細] fileror-sample2-5_2.jpg 364件 [詳細] fileror-sample2-5_1.jpg 415件 [詳細]

リロード   新規 編集 凍結解除 差分 添付 複製 名前変更   ホーム 一覧 単語検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS
Last-modified: 2012-08-08 (水) 23:25:34 (2928d)