簡體   English   中英

Rails:如何將購物車保存到用戶會話中?

[英]Rails: How to save a cart to a user session?

在我的應用程序中,我設計了一個購物車,並遵循與《 使用Rails 4進行敏捷Web開發 》一書中的布局相似的格式,但我遇到了一個小問題。 因此,用戶可以將商品添加到購物車,查看他們的購物車,並查看每個商品的價格以及總計。 我遇到的問題是,當用戶將商品放入購物車然后退出時,即使其他用戶登錄,購物車也將商品保留在購物車中。我認為正確的方法是每個用戶都有自己的個人大車。

這是我的用戶模型和控制器

class User < ActiveRecord::Base
  has_one :cart 
  # :confirmable, :lockable, :timeoutable and :omniauthable
  # :confirmable, :lockable, :timeoutable and :omniauthable
  has_secure_password
  validates :email, presence: true
end

class UsersController < ApplicationController
  def new
    @user = User.new
  end

  def show
    @user = User.find(params[:id])
  end

  def create
    @user = User.new(user_params)
      if @user.save
        session[:user_id] = @user.id
        redirect_to @user
      else
        render 'new'
      end
  end

  def edit
    @user = User.find(params[:id])
  end

  def update
    @user = User.find(params[:id])
      if @user.update_attributes(user_params)
        redirect_to @user
      end
  end

  private
  def user_params
    params.require(:user).permit(:first_name, :admin, :last_name, :email, :password, :password_confirmation, :phone_number, :address_one, :address_two, :city, :country, :state, :zip)
    end
end

我的購物車模型和控制器

class Cart < ActiveRecord::Base
  has_many :order_items
  belongs_to :user
  has_many :line_items, dependent: :destroy

  def add_part(part_id)
    current_part = line_items.find_by(part_id: part_id)
    if current_part
      current_part.quantity += 1
    else
      current_part = line_items.build(part_id: part_id)
    end
    current_part
  end

  def total_price
    line_items.to_a.sum { |item| item.total_price}
  end 
end

class CartsController < ApplicationController
  before_action :set_cart, only: [:show, :edit, :update, :destroy]
  rescue_from ActiveRecord::RecordNotFound, with: :invalid_cart

  def show
    @cart = Cart.find(params[:id])
  end

  def edit
    @cart = Cart.new(cart_params)
  end

  def update
    @cart = Cart.find(params[:id])
      if @cart.update_attributes(cart_params)
        redirect_to @cart
      end
  end

  def destroy
    @cart.destroy if @cart.id == session[:cart_id]
    session[:cart_id] = nil
    respond_to do |format|
      format.html { redirect_to root_path }
      format.json { head :no_content }
  end
end

  private
  def cart_params
    params.require(:cart).permit(:user_id)
    end

   def invalid_cart
     logger.error "Attempt to access invalid cart #{params[:id]}"
     redirect_to root_path, notice: "Invalid cart"
   end
end

以及我的訂單項控制器和當前模塊(訂單項將零件與布局中的購物車相關聯)

class LineItemsController < ApplicationController
  include CurrentCart
  before_action :set_cart, only: [:create]
  before_action :set_line_item, only: [:show, :edit, :update, :destroy]


  def create
    part = Part.find(params[:part_id])
    @line_item = @cart.add_part(part.id)

    respond_to do |format|
       if @line_item.save
         format.html { redirect_to @line_item.cart }
        format.json { render action: 'show', status: :created,
          location: @line_item }
        else
        format.html { render action: 'new' }
        format.json { render json: @line_item.errors,
        status: :unprocessable_entity }
      end
    end
  end
end

module CurrentCart
  extend ActiveSupport::Concern

  private

      def set_cart
        @cart = Cart.find(session[:cart_id])
      rescue ActiveRecord::RecordNotFound
        @cart = Cart.create
        session[:cart_id] = @cart.id
      end
    end 

關於如何使一輛購物車與一個用戶相關聯的任何建議將對您大有幫助:)如果需要更多信息,請詢問。 再次感謝!

哈哈哈! 我完成了整本書,卻從未意識到這個錯誤!

是的...所以會議內容很可愛,但是您可以通過執行以下操作始終使其更安全:

def set_cart
    @cart = Cart.find_by(id: session[:cart_id], user: session[:user_id])
  rescue ActiveRecord::RecordNotFound
    @cart = Cart.create
    session[:cart_id] = @cart.id
  end

現在,我知道您沒有session[:user_id] ,但是我想您已經對完成它有一個很好的主意。 ;)

提示:登錄

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM