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加入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,所以我們現在要去修改路由
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。
fix routes.rb
resources :items do
member do
get :add_cart
end
end我們會有一個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
我們對外是用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
endfix app/views/layouts/application.html.erb
<h1>對外頁面:public</h1>
<div>購物車數量<span class="cart_counter"><%= get_cart_count %></span></div>然後檢查頁面時發現噴了,大概是因為我的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由於我的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