Rails会话变量(购物车)

时间:2014-12-11 15:55:07

标签: ruby-on-rails session session-variables cart

我试图保存客户可以在会话变量中添加到购物车的商品。 下面是购物车控制器中的索引方法。项目的ID保存在@idtemp中。接下来,我创建一个新的数组会话[:content]。然后我找到ID保存在@idtemp中的项目并将其作为数组返回,在视图中使用该数组来显示表格。问题是,每次添加一个项目并调用索引函数时,session [:contenc]设置为[],删除购物车,这意味着新添加的项目将覆盖最后一个项目。 现在我希望这个被修复,以便新添加的项目被添加到数组而不会覆盖最后一个,但我不知道如何。我试图在索引之外初始化会话变量,但这不起作用。我知道这很容易,但我很累,无法弄明白。

def index

  @idtemp = session[:cart]

  session[:content] = []
  session[:content] = session[:content] << (Artikel.find([@idtemp]))

  @cart = session[:content]

-----查看:

  &lt;%@ cart.each do | id,quantity | %GT;       ...       ...

3 个答案:

答案 0 :(得分:0)

如果我是你,我会将购物车及其内容存储在数据库中。然后,所有会话要做的就是记住购物车ID或用户的ID,如果他们已经登录(一旦你有了用户就可以获得购物车)。我设置了这样的东西(你可以调整你自己的架构 - Artikle或其他什么代替产品)

class Cart
  belongs_to :user
  has_many :cart_products

class CartProduct
  belongs_to :cart
  belongs_to :product
  #extra field - quantity

加载页面时,查看是否有会话[:cart_id]。如果你这样做,你可以加载购物车及其相关产品(如果需要)。如果没有,则创建一个购物车对象并将会话[:cart_id]设置为该对象。

如果您有登录用户(即会话[:user_id]或某些人),那么您可以为该用户设置current_user,并设置他们的购物车。

我会通过ApplicationHelper

中的一些受保护的方法来管理它
#in application.rb
def current_user
  if @current_user
    return @current_user
  elsif session[:user_id] && user = User.where(:id => session[:user_id]).first
    @current_user = user
    return @current_user
  end
end

#there's a bit of repetition in here but it should give you the idea
def current_cart
  unless @current_cart
    if current_user
      cart = current_user.cart || Cart.create(:user => current_user)
      @current_cart = cart
    elsif session[:cart_id]
      @current_cart = Cart.where(:id => session[:cart_id]).first || Cart.create
    else
      @current_cart = Cart.create
    end
  end
  return @current_cart
end

现在,只要您想在控制器中查看当前用户或当前购物车并查看代码,只需说出current_usercurrent_cart即可。每个方法中的实例变量意味着如果它在此请求中被设置了一次,那么它将不再使用逻辑 - 它将只使用它已经保存在实例变量中的逻辑。

答案 1 :(得分:0)

好的,调整你现有的系统,我会这样做。我们将有一个会话变量,它是存储Artikels的ID和每个的数量的哈希,具有以下结构:session[:cart] = {123 => 1, 456 => 2}其中123和456是Artikel ID。

def add
  session[:cart] ||= {}
  session[:cart][params[:id]] ||= 0
  session[:cart][params[:id]] += 1
end

def index 
  session[:cart] ||= {}
end

现在在你看来你可以说

<% session[:cart].each do |artikel_id, quantity| %>
  <% artikel = Artikel.where(:id => artikel_id).first %>
  ...

答案 2 :(得分:0)

这是我不明白的:

def index
@idtemp = session[:cart]               # @idtemp is now an ID e.g. '1'
session[:inhalt] = []                  # session[:inhalt] is now an empty array []
addedarticle = Artikel.find(@idtemp)   # addedarticle is an article e.g.:{ID=>'1',title=>'Mouse'}
session[:inhalt].concat([addedarticle]) # session[:inhalt]  is now  [{...}] where {...} = article
@cart = session[:inhalt]                # @cart = [{...}]
end

这很有效。一个项目被添加到购物车中,@ cart是一个包含该项目的数组,现在可以在视图中使用它。现在唯一需要做的就是确保下一个添加的项不会覆盖旧的ond。你说我可以简单地用session [:inhalt] || = []替换session [:inhalt] = [], 但是,这样做会导致错误:

Cart#index中的NoMethodError

“#”的未定义方法`title':String

<% @cart.each do |id| %>
        <tr>
          <td><%= image_tag id.Image_URL %></td>
          <td>
            <div class="title"><%=  id.title %></div>
            <br>

在我看来,@ cart没有被正确“填充”。它应该是一系列文章(=哈希),例如[{id =&gt; 1,title ='mouse'},{id =&gt; 2,title ='whatever'}],所以我可以用每个do方法迭代它并显示它们。但根据错误,它试图从字符串中提取标题。可能是什么原因? 如果我能解决这个问题,我就完成了任务。顺便说一句,谢谢你帮助我到目前为止:)