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

学生向けにプログラミングを無料で解説。Java、C++、Ruby、PHP、データベース、Ruby on Rails, Python, Django

Rails導入編 | カート機能の実装 | 16 | エラー処理

↓↓クリックして頂けると励みになります。



15 | セッションカートの改良】 << 【ホーム】 >> 【17 | カートの仕上げ





例外が発生したときは例外を無視せずに処理を行うようにします。
まずRailsの「logger」機能を使ってエラーが発生した事実を内部ログファイルに記録します。
次にページを再表示して「無効なカートです」程度の短いメッセージを出力し、ユーザーがサイトを利用し続けられるようにします。


Railsにはエラー処理と通知に役立つ「フラッシュ」という便利な機能があります。
フラッシュはリクエストを処理する過程でオブジェクトを格納できます。
フラッシュに格納されたオブジェクトはそのセッションの次のリクエストの処理が終わるまで使うことができます。
その後は自動的に削除されます。


「SampleCart/app/controllers」フォルダにある「carts_controller.rb」ファイルを下記のように変更します。
この変更により、無効なカートidが指定された場合には例外が補足されてその問題が通知されるようになります。
最初に3行目に「rescue_from ActiveRecord::RecordNotFound, with: :invalid_cart」の記述を追加し、「invalid_cart()」メソッドをprivateの下の72行目に追加します。


記述編集 【SampleCart/app/controllers/carts_controller.rb】

class CartsController < ApplicationController
  before_action :set_cart, only: %i[ show edit update destroy ]
  rescue_from ActiveRecord::RecordNotFound, with: :invalid_cart

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

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

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

  # GET /carts/1/edit
  def edit
  end

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

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

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

  # DELETE /carts/1 or /carts/1.json
  def destroy
    @cart.destroy!

    respond_to do |format|
      format.html { redirect_to carts_url, notice: "Cart was successfully destroyed." }
      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

    # Only allow a list of trusted parameters through.
    def cart_params
      params.fetch(:cart, {})
    end

    def invalid_cart
      logger.error "無効なカート(#{params[:id]})にアクセスしようとしました。"
      redirect_to markets_index_url, notice: '無効なカートです。'
    end
  
end



フラッシュメッセージを表示させる記述をレイアウトファイルに追加します。
以下の記述を「SampleCart/app/views/layouts/application.html.erb」ファイルの20行目に追加して下さい。

    <!-- フラッシュメッセージ -->
    <% if notice %>
      <div class="alert alert-success text-center" role="alert">
          <%= notice %>
      </div>
    <% end %>



記述追加 【SampleCart/app/views/layouts/application.html.erb】20行目

<!DOCTYPE html>
<html>
  <head>
    <title>SampleCart</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
    <%= javascript_importmap_tags %>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
  </head>

  <body>

    <!-- ナビゲーションバー -->
    <%= render  "shared/navbar" %>

    <!-- フラッシュメッセージ -->
    <% if notice %>
      <div class="alert alert-success text-center" role="alert">
          <%= notice %>
      </div>
    <% end %>

    <%= yield %>
  </body>
</html>



ブラウザでhttp://localhost:3000/carts/wibbleと無効なアドレスを入力します。
http://localhost:3000/」にリダイレクトされ、「無効なカートです。」とフラッシュメッセージが表示されます。

フラッシュメッセージの表示
フラッシュメッセージの表示



ログファイルは「SampleCart/log」フォルダに「development.log」という名前で保存されています。


確認 【SampleCart/log/development.log】

Started GET "/carts/wibble" for ::1 at 2024-01-19 10:06:21 +0900
Processing by CartsController#show as HTML
  Parameters: {"id"=>"wibble"}
  [1m[36mCart Load (0.3ms)[0m  [1m[34mSELECT "carts".* FROM "carts" WHERE "carts"."id" = $1 LIMIT $2[0m  [["id", nil], ["LIMIT", 1]]
  ↳ app/controllers/carts_controller.rb:64:in `set_cart'
無効なカート(wibble)にアクセスしようとしました。
Redirected to http://localhost:3000/
Completed 302 Found in 14ms (ActiveRecord: 2.9ms | Allocations: 4965)



他人がカートへのアクセスすることも禁止しなければなりません。
そのためには許可されたパラメーターのリストからcart_idを削除する記述をします。
その部分は「SampleCart/app/controllers」フォルダにある「line_items_controller.rb」ファイルの72行目の記述から「cart_id」の記述を削除しています。


記述削除 【SampleCart/app/controllers/line_items_controller.rb】72行目

class LineItemsController < ApplicationController

  include CurrentCart
	before_action :set_cart, only: [:create]
  before_action :set_line_item, only: %i[ show edit update destroy ]

  # GET /line_items or /line_items.json
  def index
    @line_items = LineItem.all
  end

  # GET /line_items/1 or /line_items/1.json
  def show
  end

  # GET /line_items/new
  def new
    @line_item = LineItem.new
  end

  # GET /line_items/1/edit
  def edit
  end

  # POST /line_items or /line_items.json
  def create
    good = Good.find(params[:good_id])
    @line_item = @cart.add_good(good)

    respond_to do |format|
      if @line_item.save
        format.html { redirect_to line_item_url(@line_item), notice: "商品をカートに追加しました。" }
        format.json { render :show, status: :created, location: @line_item }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @line_item.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /line_items/1 or /line_items/1.json
  def update
    respond_to do |format|
      if @line_item.update(line_item_params)
        format.html { redirect_to line_item_url(@line_item), notice: "Line item was successfully updated." }
        format.json { render :show, status: :ok, location: @line_item }
      else
        format.html { render :edit, status: :unprocessable_entity }
        format.json { render json: @line_item.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /line_items/1 or /line_items/1.json
  def destroy
    @line_item.destroy!

    respond_to do |format|
      format.html { redirect_to line_items_url, notice: "Line item was successfully destroyed." }
      format.json { head :no_content }
    end
  end

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

    # Only allow a list of trusted parameters through.
    def line_item_params
      params.require(:line_item).permit(:good_id)
    end
end



15 | セッションカートの改良】 << 【ホーム】 >> 【17 | カートの仕上げ




↓↓クリックして頂けると励みになります。