↓↓クリックして頂けると励みになります。
【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 | カートの仕上げ】
↓↓クリックして頂けると励みになります。