ruby-on-rails - 购物车,可以使用 Devise 的 session 功能吗?

标签 ruby-on-rails ruby-on-rails-4 devise e-commerce

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

这可以在 Devise gem 中完成还是我必须实现我自己的 session 模型才能使其工作?

最佳答案

您需要处理自己的 session 数据 - 并不意味着您需要 session model尽管。
我们已经实现了你正在寻找的东西。它使用 session 模型工作,但使用我为您推荐的相同基本功能:

#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

session
根据 Rails documentation :

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.


据我所知, session 是为每个用户存储数据的小型 cookie 文件。这些是不明确的(为每个用户创建 - 无论他们是否登录),这意味着我会将它们用于您的购物车
我们使用 Sessions通过存储原始数据来创建购物车数据 id session 中购物车产品的

设计
关于设计的说明 - 您要问的与设计 gem 无关。 Devise 是一个身份验证系统,这意味着它会处理用户是否有权访问您的应用程序;它不处理购物车数据
虽然 Devise 将数据存储在 sessions ,您需要定义自己的 session您购物车的数据。我们使用 cart 来做到这一点具有上述型号代码的 Controller :
#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

关于ruby-on-rails - 购物车,可以使用 Devise 的 session 功能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23154206/

相关文章:

javascript - 用 Cucumber 和 Capybara 测试排序

ruby-on-rails - Rails - 大型数据库查询

mysql - Rails 4 - Mysql2::错误:索引列大小太大

ruby-on-rails-4 - ActiveAdmin 重复嵌套表单并删除复选框不起作用

ruby-on-rails - rails 4.2 : Eager-loading has_many relation with STI

ruby-on-rails - 如何使用 Docker 生成 Rails 迁移

ruby-on-rails - FriendlyID Controller 名称验证包含问题

ruby-on-rails - ActionController::UnknownFormat in Devise::SessionsController#rails 4 中的新功能

ruby-on-rails - 使用 CanCan 来授权资源,但不希望它用于所有操作

ruby-on-rails - 在RoR View 中获得{{attribute}} {{message}}