购物车,可以使用 Devise 的会话功能吗? [英] shopping cart, possible to use Devise's session functionality?

查看:25
本文介绍了购物车,可以使用 Devise 的会话功能吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个电子商务网站,我需要实现购物车功能.我希望客户无需事先注册即可将产品添加到他们的购物车中,因此我想我可以通过会话来实现这一点.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆