如何将Act_as_shopping_cart与用户绑定

时间:2015-08-17 12:40:49

标签: ruby-on-rails ruby shopping-cart

我正在做我的第一个项目,我需要你的帮助。 我正在使用act_as_shopping_cart gem和Rails Tutorial中的用户模型。 我如何绑定用户和购物车?我尝试绑定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

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

1 个答案:

答案 0 :(得分:1)

Rails让你可以做很多“魔术”,其中一个地方的代码神奇地影响应用程序中其他地方的行为,两者之间没有明确的联系。这真的很强大,但我认为对于初学者来说,这也是一个巨大的问题;当你学习Rails时,很难跟踪一个东西是如何与另一个东西相关的,所以在继承链中隐藏这些连接几乎是残酷的。

所以,如果你在一个Rails魔术压倒性的地方(它当然对我而言),我的建议是编写愚蠢的代码,使连接成为本地和简单尽可能。有时甚至当它偏离“Rails方式”时也值得这样做;你宁愿拥有“正确的Rails”代码,还是易于理解和易于维护的代码?

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

puts session

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

通常,在所有相关控制器操作的开头添加大量puts语句是一种很好的(并且非常简单)方式,可以深入了解应用程序的思路。

希望有所帮助!