简体   繁体   中英

Ruby on rails: How to ajax cart when change quantity items in cart, cart save in session, not database?

UPDATE: i found solution for my problems. Thanks for your support!

I'm doing simple shopping cart with ajax by ruby on rails.

I want to ajax my cart page when change quantity item of cart. I found some solutions but they save cart into database. How to resolve my solution without save cart into database?

I wonder:

  • Can i use ajax in file view or include ajax file in view? As way i tried in PHP?
  • If i use ajax default on rails, how to render input field(change value) in file increment/decrement_item.js.erb (file render partial without reload page)? I don't use cart as active record, so render @cart or @item is impossible(or i dont know how to make it possible).

I also have some idea for my problem. But it's so hard. Exp: I think i will create a _quantity_item display input quantity. And i can use it for index view of cart and render in increment/decrement.js.erb but fail. So sad!

My view display cart(short):

<% @cart.each_with_index do |item, index| %>
      <tr>
        <th scope="row"><%= index %></th>
        <td><img src="<%= asset_path(item[0].image) %>" style="width:100px"></td>
        <td><%= item[0].name %></td>
        <td><%= money_vn_format(item[0].price) %></td>
        <td>
          <div class="quantity">
            <%= button_to '-', decrement_item_path(item[0].id), class: 'btn minus1', method: :put, remote: true %>
           <input class="quantity" min="0" value="<%= item[1] %>" type="number"> 
             <%= button_to '+', increment_item_path(item[0].id), class: 'btn add1', method: :put, remote: true %>
          </div>
        </td>
        <td><%= money_vn_format(item[0].price * item[1]) %></td>
        <td><%= link_to 'Remove', delete_cart_path(item[0].id) %></td>
      </tr>
    <% end %>

and code CartsController:

# frozen_string_literal: true

class CartsController < ApplicationController
  def index
    save_session_to_cart if session.key? :cart
  end

  def add
    session[:cart] ||= {}
    session[:cart][params[:id]] = 1 unless session[:cart].key? params[:id]
    save_session_to_cart

    redirect_to carts_index_path
  end

  def delete
    session[:cart].delete params[:id]
    redirect_to carts_index_path
  end

  def destroy
    reset_session
    redirect_to carts_index_path
  end

  def increment_item
    session[:cart][params[:id]] += 1
    save_session_to_cart
    redirect_to carts_index_path
  end

  def decrement_item
    session[:cart][params[:id]] -= 1 if session[:cart][params[:id]] > 1
    save_session_to_cart
    redirect_to carts_index_path
  end

  private

  def save_session_to_cart
    @cart = []
    @total = 0
    session[:cart].each do |product_id, quantity|
      @cart << [Product.find(product_id), quantity]
      @total += Product.find(product_id).price * quantity
    end
    @cart
  end
end

Check out this answer by crispychicken Rails: How to store data in session? . The poster suggests playing around with the session variable in rails.

Or conversely if you want it to be simpler, make use of the browser's local storage using JS.

I'd do that using the browser's local storage, with javascript. You can save values with this:

localStorage.setItem('items-count', 1);

And read them back like this:

localStorage.getItem('items-count');

But bare in mind that if the user opens a different browser or uses another device, the shopping cart will be empty.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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