学生向けプログラミング入門

学生向けにプログラミングを解説。Java、C++、Ruby、PHP、データベース

Ruby on RailsでWebアプリケーション開発その22 買い物カートを空にする

<<前  [TOP]  次>>


カートの中身を空にする機能を実装していきます。
まずはボタンの実装です。
「app/views/carts」フォルダにある「show.html.erb」ファイルを以下のように編集します。


【app/views/carts/show.html.erb】

<% if notice %>
<p id="notice"><%= notice %></p>
<% end %>
<br>
<h1>Railsはじめてマート</h1>
<h2>   カートに追加された商品</h2>
<br>
<span>  </span><%= link_to '買い物を続ける', market_path, :class => 'btn' %><span>
<br>
<br>
<table>
	<tr>
		<th></th>
		<th>商品名</th>
		<th>価格</th>
		<th>数量</th>

	</tr>
		<% @cart.line_items.each do |item| %>
		<tr>
			<td text-align:center;><img height="80" src="<%=h item.good.image_url %>"/></td>
			<td text-align:center;><font size="4"><%= item.good.title %></font></td>
			<td text-align:center;><font size="4"><%= (item.good.price).to_i %></font></td>
			<td text-align:center;><font size="4"><%= item.quantity %></font></td>
		</tr>
		<% end %>

</table>
<br>
<%= button_to 'カートを空にする', @cart, method: :delete, data: {confirm: 'カートを空にして本当によろしいですか?'}, class: 'fbtn' %>

「カートを空にする」ボタンを追加している記述は以下の部分です。

<%= button_to 'カートを空にする', @cart, method: :delete, data: {confirm: 'カートを空にして本当によろしいですか?'}, class: 'fbtn' %>



次にcartsコントローラのdestroy()メソッドを修正します。


【app/controllers/carts_controller.rb】

class CartsController < ApplicationController
  before_action :set_cart, only: [:show, :edit, :update, :destroy]

  # GET /carts
  # GET /carts.json
  def index
    @carts = Cart.all
  end

  # GET /carts/1
  # GET /carts/1.json
  def show
  end

  # GET /carts/new
  def new
    @cart = Cart.new
  end

  # GET /carts/1/edit
  def edit
  end

  # POST /carts
  # POST /carts.json
  def create
    @cart = Cart.new(cart_params)

    respond_to do |format|
      if @cart.save
        format.html { redirect_to @cart, notice: 'Cart was successfully created.' }
        format.json { render :show, status: :created, location: @cart }
      else
        format.html { render :new }
        format.json { render json: @cart.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /carts/1
  # PATCH/PUT /carts/1.json
  def update
    respond_to do |format|
      if @cart.update(cart_params)
        format.html { redirect_to @cart, notice: 'Cart was successfully updated.' }
        format.json { render :show, status: :ok, location: @cart }
      else
        format.html { render :edit }
        format.json { render json: @cart.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /carts/1
  # DELETE /carts/1.json
  def destroy

    @cart = current_cart
    @cart.destroy
    session[:cart_id] = nil
    respond_to do |format|
      format.html { redirect_to market_url, notice: 'カートが空になりました。' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_cart
      @cart = Cart.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def cart_params
      params.fetch(:cart, {})
    end
end



変更したのは以下の部分です。

  def destroy

    @cart = current_cart
    @cart.destroy
    session[:cart_id] = nil
    respond_to do |format|
      format.html { redirect_to market_url, notice: 'カートが空になりました。' }
      format.json { head :no_content }
    end
  end

セッションカートを削除し、「カートが空になりました。」というメッセージをつけてmarketインデックスページにリダイレクトするようにしています。


確認してみます。
f:id:MrRadiology:20180223163001j:plain


f:id:MrRadiology:20180223163056j:plain


フラッシュメッセージの見栄えが少し悪いので「app/assets/stylesheets」フォルダにある「scaffolds.scss」ファイルを編集しておきます。


【app/assets/stylesheets/scaffolds.scss】

h1:first-letter {
	font-size: 2em;
	color: #7172ac;
}

h1 {
	position: relative;
	color: #333333;
	text-shadow: 0 0 2px white;
}

h1:before {
	content: "";
	position: absolute;
	background: #9de5ff;
	width: 50px;
	height: 50px;
	border-radius: 50%;
	top: 50%;
	/* border: dashed 1px white; */
	left: -15px;
	-moz-transform: translateY(-50%);
	-webkit-transform: translateY(-50%);
	-ms-transform: translateY(-50%);
	transform: translateY(-50%);
	z-index: -1;
}

table {
  width: auto;
  border-spacing: 0;
  font-size:14px;
}

table th {
  color: #fff;
  padding: 8px 15px;
  background: #7172ac;
  background:-moz-linear-gradient(rgba(34,85,136,0.7), rgba(34,85,136,0.9) 50%);
  background:-webkit-gradient(linear, 100% 0%, 100% 50%, from(rgba(34,85,136,0.7)), to(rgba(34,85,136,0.9)));
  font-weight: bold;
  border-left:1px solid #258;
  border-top:1px solid #258;
  border-bottom:1px solid #258;
  line-height: 120%;
  text-align: center;
  text-shadow:0 -1px 0 rgba(34,85,136,0.9);
  box-shadow: 0px 1px 1px rgba(255,255,255,0.3) inset;
}

table th:first-child {
  border-radius: 5px 0 0 0;
}

table th:last-child {
  border-radius:0 5px 0 0;
  border-right:1px solid #258;
  box-shadow: 2px 2px 1px rgba(0,0,0,0.1),0px 1px 1px rgba(255,255,255,0.3) inset;
}

table tr td {
  padding: 8px 15px;
  border-bottom: 1px solid #84b2e0;
  border-left: 1px solid #84b2e0;
  text-align: center;
}

table tr td:last-child {
  border-right: 1px solid #84b2e0;
  box-shadow: 2px 2px 1px rgba(0,0,0,0.1);
}

table tr {
  background: #fff;
}

table tr:nth-child(2n+1) {
  background: #f1f6fc;
}

table tr:last-child td {
  box-shadow: 2px 2px 1px rgba(0,0,0,0.1);
}

table tr:last-child td:first-child {
  border-radius: 0 0 0 5px;
}

table tr:last-child td:last-child {
  border-radius: 0 0 5px 0;
}

table tr:hover {
  background: #fffafa;
  cursor:pointer;
}

.btn {
    position: relative;
    display: inline-block;
    font-weight: bold;
    padding: 12px 0 8px;
    text-decoration: none;
    color: #67c5ff;
    transition: .4s;
}

.btn:before{
   position: absolute;
   content: '';
   width: 100%;
   height: 4px;
   top:100%;
   left: 0;
   border-radius: 3px;
   background:#67c5ff;
   transition: .2s;
}

.btn:after{
   position: absolute;
   content: '';
   width: 100%;
   height: 4px;
   top:0;
   left: 0;
   border-radius: 3px;
   background:#67c5ff;
   transition: .2s;
}

.btn:hover:before {
    top: -webkit-calc(100% - 3px);
    top: calc(100% - 3px);
}

.btn:hover:after {
    top: 3px;
}

body {
  background-color: #fff;
  color: #333;
  margin: 33px;
  font-family: verdana, arial, helvetica, sans-serif;
  font-size: 13px;
  line-height: 18px;
}

p, ol, ul, td {
  font-family: verdana, arial, helvetica, sans-serif;
  font-size: 13px;
  line-height: 18px;
}

pre {
  background-color: #eee;
  padding: 10px;
  font-size: 11px;
}

div {
  &.field, &.actions {
    margin-bottom: 10px;
  }
}

#notice {
 padding:12px;
 font-weight:850;
 color:#262626;
 background:#CCFFCC;
 border:2px solid #00CC00;
 width: 500px;
 font-size: 18px;
}

.field_with_errors {
  padding: 2px;
  background-color: red;
  display: table;
}

#error_explanation {
  width: 450px;
  border: 2px solid red;
  padding: 7px 7px 0;
  margin-bottom: 20px;
  background-color: #f0f0f0;

  h2 {
    text-align: left;
    font-weight: bold;
    padding: 5px 5px 5px 15px;
    font-size: 12px;
    margin: -7px -7px 0;
    background-color: #c00;
    color: #fff;
  }

  ul li {
    font-size: 12px;
    list-style: square;
  }
}

label {
  display: block;
}



変更したのは「#notice」の部分だけです。

#notice {
 padding:12px;
 font-weight:850;
 color:#262626;
 background:#CCFFCC;
 border:2px solid #00CC00;
 width: 500px;
 font-size: 18px;
}



少し見栄えが良くなりました。
f:id:MrRadiology:20180223170346p:plain


<<前  [TOP]  次>>