轨道会话变量(购物车)



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

定义索引

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

结束

-----视图:

<% @cart.每个做 |id,数量|%> ... ...

如果我是你,我会将购物车及其内容存储在数据库中。 然后,会话所要做的就是记住购物车 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]。 如果这样做,您可以根据需要加载购物车及其相关产品。 如果没有,则创建一个购物车对象并将 session[:cart_id] 设置为该对象。

如果您有登录用户(即session[:user_id]或类似用户(,则可以为该用户设置current_user,并设置他们的购物车。

我会通过应用程序助手中的一些受保护方法来管理它

#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 。 每个方法中的实例变量意味着,如果在此请求中设置了一次,那么它将不会再次使用该逻辑 - 它将只使用已保存在实例变量中的逻辑。

好的,调整您现有的系统,我会这样做。 我们将有一个会话变量,它是一个哈希,用于存储 Artikels(Artikels(的 ID 和每个 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 %>
  ...

这是我不明白的:

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。你说我可以简单地将会话[:inhalt] = []替换为会话[:inhalt] ||= [],但是,这样做会导致错误:

购物车#索引中的无方法错误

"#"的未定义方法"标题":字符串

<% @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方法迭代它并显示它们。但是根据错误,它试图从字符串中提取标题。可能是什么原因呢?如果我能解决这个问题,我就完成了任务。顺便说一句,感谢您到目前为止对我的帮助:)

最新更新