如何绑定 Act_as_shopping_cart 与用户

How to bind Act_as_shopping_cart with user

我正在做我的第一个项目,我需要你的帮助。 我正在使用 act_as_shopping_cart gem 和 Rails 教程中的用户模型。 如何绑定用户和购物车?我尝试绑定 shopping_cart.id 和 user.id,但没有成功,所有用户仍然有相同的购物车。 它是我的代码: 购物车控制器:

class ShoppingCartsController < ApplicationController
  before_filter :extract_shopping_cart

  def create
    @product = Sketchbook.find(params[:product_id])
    @shopping_cart.add(@product, @product.price)
    redirect_to shop_path
  end

  def show

  end

  private

  def extract_shopping_cart
    shopping_cart_id = session[:shopping_cart_id]
    @shopping_cart = session[:shopping_cart_id] ? ShoppingCart.find(shopping_cart_id) : ShoppingCart.create
    session[:shopping_cart_id] = @shopping_cart.id
  end
end

用户控制器:

class UsersController < ApplicationController
  before_action :logged_in_user, only: [:show, :edit, :update]
  before_action :correct_user, only: [:edit, :update]


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

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
        redirect_to user_url(@user)
        flash[:notice] = "Użytkownik stworzony"
    else
        render 'new'
    end
  end

  def edit
  end

  def update
    if @user.update_attributes(user_params)
      redirect_to user_url(current_user)
      flash[:notice] = "Dane zaktualizowane"
    else
      render 'edit'
    end
  end

  def destroy
    User.find(params[:id]).destroy
    flash[:success] = "Konto usunięte"
    redirect_to root_url
  end



  private
    def user_params
        params.require(:user).permit(:username, :name, :surname, :email, :adress, :city, :zip_code, :country, :password, :password_confirmation)
    end

    #confirms a logged user
    def logged_in_user
      unless logged_in?
        store_location 
        flash[:danger] = "Zaloguj się"
        redirect_to login_url
      end
    end

    #confirms the correct user
    def correct_user
      @user = User.find(params[:id])
      redirect_to(root_url) unless current_user?(@user)
    end
end

会话助手:

module SessionsHelper

    #log in method
    def log_in(user)
        session[:user_id] = user.id
    end

    #remember a user in a presisnet session
    def remember(user)
        user.remember
        cookies.permanent.signed[:user_id] = user.id
        cookies.permanent[:remember_token] = user.remember_token
    end

    #returns true if the given user i current user
    def current_user?(user)
        user == current_user
    end

    #forgets a presistent session
    def forget(user)
        user.forget
        cookies.delete(:user_id)
        cookies.delete(:remember_token)
    end

    # returns logged user
    def current_user
        if (user_id = session[:user_id]) #open broweser
            @current_user ||= User.find_by(id: session[:user_id])
        elsif (user_id = cookies.signed[:user_id]) #cookie is present
            user= User.find_by(id: cookies.signed[:user_id])
            if user && user.authenticated?(cookies[:remember_token])
                log_in user
                @current_user = user
            end
        end
    end

    # Returns true if the user is logged in
    def logged_in?
        !current_user.nil?
    end


    # logs out current user
    def log_out
        forget(current_user)
        session.delete(:user_id)
        @current_user = nil?
    end


    #stores the url trying to be accessed
    def store_location
        session[:forwarding_url] = request.url if request.get?
    end

    #redirect back to stored location (or to the default)
    def redirect_back_or(default)
        redirect_to(session[:forwarding_url] || default)
        session.delete(:forwarding_url)
    end
end

如果您能给我一些其他如何改进此代码的指导,我也很高兴。

Rails 让您可以做很多 "magic",其中一个地方的代码神奇地影响应用程序其他地方的行为,两者之间没有明确的联系。这真的很强大,但我认为对于初学者来说也是一个大问题;当您学习 Rails 时,很难跟踪一件事与另一件事之间的关系,因此将这些联系隐藏在继承链中几乎是残酷的。

因此,如果您身处 Rails 魔力难以抗拒的地方(对我来说肯定仍然如此),我的建议是 编写愚蠢的代码使连接尽可能本地和简单。有时即使偏离 "the Rails way" 也值得这样做;您想要 "proper Rails" 代码,还是易于理解和维护的代码?

无论如何,您的具体问题可能与会话有关。在 ShoppingCartsController 中,您通过查找 session[:shopping_cart_id] 来定义 @shopping_cart。如果多个用户(注销并以其他人身份登录后)以相同的 @shopping_cart.id 结束,那一定意味着他们的会话值相同。在相关控制器操作的开头,添加一个 puts 语句来为您提供有关会话值的额外信息(它吐出到控制台):

puts session

如果多个用户具有相同的会话值,这可能意味着当您注销并以其他人身份登录时会话未正确清除。您可以通过设置不同的会话变量来测试它,并查看它是否也从一个用户持续到另一个用户。

一般来说,在所有相关控制器操作的开头添加大量 puts 语句是了解您的应用程序正在思考什么的好方法(而且超级简单)。

希望对您有所帮助!