繁体   English   中英

Rails 会话变量(购物车)

[英]Rails session variable (shopping cart)

我正在尝试将客户可以添加到我的购物车中的项目保存在会话变量中。 下面是我在购物车控制器中的索引方法。 项目的 ID 保存在@idtemp 中。 接下来我创建一个新的数组 session[:content]。 然后找到@idtemp中保存有ID的item,将其作为数组返回,用于视图中显示表格。 问题是,每次添加商品并调用index函数时,session[:contenc]设置为[],删除购物车,这意味着新添加的商品会覆盖上一个。 现在我想要修复这个问题,以便将新添加的项目添加到数组中而不覆盖最后一个,但我不知道如何。 我试图在索引之外初始化会话变量,但这并没有以某种方式起作用。 我知道这很容易,但我已经筋疲力尽,无法弄清楚。

定义索引

  @idtemp = session[:cart]

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

  @cart = session[:content]

结尾

- - -看法:

<% @cart.each do |id,quantity| %> ... ...

如果我是你,我会将购物车及其内容存储在数据库中。 然后会话要做的就是记住购物车 id 或用户的 id,如果他们登录了(一旦你有了用户,你就可以得到购物车)。 我会设置类似这样的东西(您可以根据自己的架构进行调整 - Artikle 或其他任何东西而不是 Product)

class Cart
  belongs_to :user
  has_many :cart_products

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

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

如果您有一个登录用户(即 session[: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_user ,只需说current_usercurrent_cart 每个方法中的实例变量意味着如果它在这个请求中设置了一次,那么它不会再次使用逻辑——它只会使用它已经保存在实例变量中的那个。

好的,调整您现有的系统,我会这样做。 我们将有一个会话变量,它是一个散列,存储了 Artikel 的 id 和每个的数量,结构如下: session[:cart] = {123 => 1, 456 => 2}其中 123 和 456 是 Artikel身份证。

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 %>
  ...

这是我不明白的:

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] = [],但是,这样做会导致错误:

购物车中没有方法错误#index

“#”的未定义方法`title':字符串

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM