Step.13 購物車的邏輯 - Azraeil/JCcart_Note GitHub Wiki

修改對外頁面的畫面

現在我們跳到localhost:3000/就能看到最外面的頁面

fix app/views/items/index.html.erb

<p id="notice"><%= notice %></p>

<h1>Listing Items</h1>

<table>
  <thead>
    <tr>
      <th>圖片</th>
      <th>名稱</th>
      <th>管理</th>
    </tr>
  </thead>

  <tbody>
    <% @items.each do |item| %>
      <tr>
        <td><%= image_tag item.cover.url(:icon) %></td>
        <td><%= item.name %>(<%= item.price %>)</td>
        <td>加入購物車</td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

這邊講一下image_tag,如果我們url設為:icon,每張圖就會顯示我們先前設定的150x150

<td><%= image_tag item.cover.url(:icon) %></td>

如果我們url設為:original,圖片就會顯示原始大小

<td><%= image_tag item.cover.url(:original) %></td>
對外頁面加入分頁效果

由於先前用scaffold沒有分頁,所以我們去controller把頁面改

fix app/controllers/items_controller.rb

def index
  @items = @paginate = Item .includes(:cate).paginate(:page => params[:page])
end

購物車的action

加入add_cart action

fix app/controllers/items_controller.rb

before_action :set_item, only: [:show, :edit, :update, :destroy]

def add_cart

end


def index
  ...
end

...
...

我們預計加入購物車add_cart這個action後,會給我們一個id,所以我們現在要去修改路由

解釋member與collection

fix routes.rb,這邊我們先解釋member與collection

Rails.application.routes.draw do

  resources :cates
  resources :items do
    member do
      get :yooo
    end
    collection do
      get :hooo
    end
  end

  ...
  ...

我們可以rake routes來看他的效果

 yooo_item GET    /items/:id/yooo(.:format)                    items#yooo
hooo_items GET    /items/hooo(.:format)                        items#hooo

我們可以看到yooo有idhooo則沒有

member一定會有id,collection是一個集合體。集合體是什麼,譬如說是首頁、列表頁...,這種綜合體的東西都在collection裡面。一個單一的東西,譬如說某一個產品的頁面,某位使用者的頁面、某類別的頁面,就會有id,就要使用member。

add_cart的路由設定

fix routes.rb

resources :items do
  member do
    get :add_cart
  end
end

add_cart action 的設計

我們會有一個params[:id]在網址內,就像我們在上面解釋member會匹配的網址/items/:id/yooo(.:format)那樣

fix app/controllers/items_controller.rb

def add_cart
  session[:cart] || = {}
  item = Item.where(:id => params[:id]).first

  if item
    session[:cart][item.id] ||= 0
    session[:cart][item.id] += 1  
  end

  render :json => {:counter => session[:cart].length}.to_json
end

購物車的session,一開始

session[:cart] || =

接下來就依你設計的不同,而使用hash或array寫。用hash會比較好寫,除非你要做「逛過的足跡」這種功能才要用array寫

session[:cart] || = {}

由於我們要取的是params[:id],我們要先驗證有沒有它

item = Item.where(:id => params[:id]).first

Item.where()這一串你把它想成SQL的WHERE就很好懂了,他就只是個做判斷式的語法,我們用where()判斷出有id,就把他存到params[:id] 就把它取出來。

如果有item的話

if item
  session[:cart][item.id] ||= 0
  session[:cart][item.id] += 1  
end

這是在說,我按一下,數字就+1買一個商品,按十次就+10買十個商品

最後,我們要回傳

render :json => {:counter => session[:cart].length}.to_json

get_cart_count helper

我們對外是用AJAX取這數字,但在此之前我們先建一個helper來取sessino[:cart]

fix app/helpers/application_helper.rb

module ApplicationHelper
  def get_cart_count
    if session[:cart]
      return session[:cart].length
    else
      return 0  
    end
  end
end

在application中使用get_cart_count helper

fix app/views/layouts/application.html.erb

<h1>對外頁面:public</h1>
<div>購物車數量<span class="cart_counter"><%= get_cart_count %></span></div>

fix items_controller

然後檢查頁面時發現噴了,大概是因為我的rails版本跟JC不同,我是噴出

app/controllers/items_controller.rb:4: syntax error, unexpected '=' session[:cart] || = {} ^

檢查良久發現,我在session[:cart]的宣告時寫成|| =,||與=之間多一個空格就噴錯了,他們之間不能有空格

fix app/controllers/items_controller.rb

def add_cart
  session[:cart] ||= {}
  ...
  ...
end

順手改成JC版的items_controller

由於我的rails沒生成respond_with,老實說沒必要改,不過JC都說很多東西用不到,就順手改成JC在影片中的樣子吧

fix app/controllers/items_controller.rb

完整的code

class ItemsController < ApplicationController

  def add_cart
    session[:cart] ||= {}
    item = Item.where(:id => params[:id]).first

    if item
      session[:cart][item.id] ||= 0
      session[:cart][item.id] += 1
    end

    render :json => {:counter => session[:cart].length}.to_json
  end


  # GET /items
  def index
    @items = @paginate = Item .includes(:cate).paginate(:page => params[:page])
  end

  # GET /items/1
  def show
    @item = Item.find(params[:id])
  end

end
⚠️ **GitHub.com Fallback** ⚠️