购物车,可以使用 Devise 的会话功能吗? [英] shopping cart, possible to use Devise's session functionality?
问题描述
我正在编写一个电子商务网站,我需要实现购物车功能.我希望客户无需事先注册即可将产品添加到他们的购物车中,因此我想我可以通过会话来实现这一点.
I am writing an ecommerce website and I need to implement a shopping cart feature. I want the customers to be able to add products to their cart without signing up beforehand, so I figured I would accomplish this through sessions.
这可以在 Devise gem 中完成还是我必须实现我自己的会话模型才能使其工作?
Can this be done in the Devise gem or will I have to implement my own session model for this to work?
推荐答案
您需要处理自己的会话数据 - 并不意味着您需要 会话模型.
You'll need to handle your own session data - doesn't mean you'll need a session model though.
我们已经实现了您要查找的内容.它使用会话模型工作,但使用我为您推荐的相同基本功能:
We've implemented what you're looking for. It works using a session model, but uses the same base functionality I'd recommend for you:
#app/models/cart_session.rb
class CartSession
#Initalize Cart Session
def initialize(session)
@session = session
@session[:cart] ||= {}
end
#Cart Count
def cart_count
if (@session[:cart][:products] && @session[:cart][:products] != {})
@session[:cart][:products].count
else
0
end
end
#Cart Contents
def cart_contents
products = @session[:cart][:products]
if (products && products != {})
#Determine Quantities
quantities = Hash[products.uniq.map {|i| [i, products.count(i)]}]
#Get products from DB
products_array = Product.find(products.uniq)
#Create Qty Array
products_new = {}
products_array.each{
|a| products_new[a] = {"qty" => quantities[a.id.to_s]}
}
#Output appended
return products_new
end
end
#Qty & Price Count
def subtotal
products = cart_contents
#Get subtotal of the cart items
subtotal = 0
unless products.blank?
products.each do |a|
subtotal += (a[0]["price"].to_f * a[1]["qty"].to_f)
end
end
return subtotal
end
#Build Hash For ActiveMerchant
def build_order
#Take cart objects & add them to items hash
products = cart_contents
@order = []
products.each do |product|
@order << {name: product[0].name, quantity: product[1]["qty"], amount: (product[0].price * 100).to_i }
end
return @order
end
#Build JSON Requests
def build_json
session = @session[:cart][:products]
json = {:subtotal => self.subtotal.to_f.round(2), :qty => self.cart_count, :items => Hash[session.uniq.map {|i| [i, session.count(i)]}]}
return json
end
end
会话
根据 Rails 文档:
大多数应用程序需要跟踪特定的特定状态用户.这可能是购物篮的内容或用户 ID当前登录的用户.没有会议的想法,用户必须在每个要求.如果有新用户,Rails 将自动创建一个新会话访问应用程序.如果用户,它将加载现有会话已使用该应用程序.
Most applications need to keep track of certain state of a particular user. This could be the contents of a shopping basket or the user id of the currently logged in user. Without the idea of sessions, the user would have to identify, and probably authenticate, on every request. Rails will create a new session automatically if a new user accesses the application. It will load an existing session if the user has already used the application.
据我所知,会话是为每个用户存储数据的小型 cookie 文件.这些是不明确的(为每个用户创建 - 无论他们是否登录),这意味着我会将它们用于您的购物车
Sessions, to my knowledge, are small cookie files storing data for each user. These are ambiguous (are created for every user - regardless of whether they are signed in or not), which means I'd use them for your cart
我们使用 Sessions
通过在会话中存储购物车产品的原始 id
来创建购物车数据
We use Sessions
to create cart data by storing raw id
's of the cart products in the session
设计
关于 Devise 的说明 - 您所询问的与 Devise 宝石无关.Devise 是一个身份验证系统,这意味着它会处理用户是否有权访问您的应用程序;它不处理购物车数据
A note on Devise - what you're asking about has nothing to do with the Devise gem. Devise is an authentication system, meaning it handles if a user has access to your app; it doesn't handle shopping cart data
虽然 Devise 将数据存储在 sessions
中,但您需要为您的购物车定义自己的 session
数据.我们使用带有上述模型代码的 cart
控制器来做到这一点:
Whilst Devise stores data in sessions
, you'll need to define your own session
data for your cart. We do this using a cart
controller with the model code above:
#config/routes.rb
get 'cart' => 'cart#index', :as => 'cart_index'
post 'cart/add/:id' => 'cart#add', :as => 'cart_add'
delete 'cart/remove(/:id(/:all))' => 'cart#delete', :as => 'cart_delete'
#app/controllers/cart_controller.rb
class CartController < ApplicationController
include ApplicationHelper
#Index
def index
@items = cart_session.cart_contents
@shipping = Shipping.all
end
#Add
def add
session[:cart] ||={}
products = session[:cart][:products]
#If exists, add new, else create new variable
if (products && products != {})
session[:cart][:products] << params[:id]
else
session[:cart][:products] = Array(params[:id])
end
#Handle the request
respond_to do |format|
format.json { render json: cart_session.build_json }
format.html { redirect_to cart_index_path }
end
end
#Delete
def delete
session[:cart] ||={}
products = session[:cart][:products]
id = params[:id]
all = params[:all]
#Is ID present?
unless id.blank?
unless all.blank?
products.delete(params['id'])
else
products.delete_at(products.index(id) || products.length)
end
else
products.delete
end
#Handle the request
respond_to do |format|
format.json { render json: cart_session.build_json }
format.html { redirect_to cart_index_path }
end
end
end
这篇关于购物车,可以使用 Devise 的会话功能吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!