2016-06-13 2 views
0

У меня есть корзина Rails для клиента, который работает, но только на второй попытке попробовать «добавить в корзину».Проблема с Rails с корзиной пользователя

Поэтому каждый раз, когда я нажимаю «добавить в корзину», тележка пуста в первый раз. Но при второй попытке элемент добавляется в корзину.

Что я делаю неправильно?

Вот код контроллера клиента:

class Customer::CartsController < ApplicationController 
    before_action :authenticate_user! 
    def show 
    @cart = if current_user 
    current_user.cart ||= Cart.find_by(session[:cart_id]) 
    session[:cart_id] = nil if current_user.cart.purchased_at 
    end 
    if session[:cart_id].nil? 
    current_user.cart = Cart.create!(user_id: params[:id]) 
    session[:cart_id] = current_user.cart.id 
    end 
    @cart = current_user.cart 
    end 
end 

Обычный контроллер Тележки

class CartsController < ApplicationController 
skip_before_action :authorize, only: [:create, :update, :destroy] 
before_action :set_cart, only: [:show, :edit, :update, :destroy] 
rescue_from ActiveRecord::RecordNotFound, with: :invalid_cart 

def index 
    @carts = Cart.all 
end 

def show 
end 

def new 
@cart = Cart.new 
end 

def edit 
end 

def create 
@cart = Cart.new(cart_params) 

respond_to do |format| 
    if @cart.save 
    format.html { redirect_to @cart, notice: 'Cart was successfully created.'} 
    format.json { render :show, status: :created, location: @cart } 
    else 
    format.html { render :new } 
    format.json { render json: @cart.errors, status: :unprocessable_entity } 
    end 
end 
end 

def update 
    respond_to do |format| 
    if @cart.update(cart_params) 
     format.html { redirect_to @cart, notice: 'Cart was successfully updated.' } 
     format.json { render :show, status: :ok, location: @cart } 
    else 
     format.html { render :edit } 
     format.json { render json: @cart.errors, status: :unprocessable_entity } 
    end 
    end 
    end 

def destroy 
    @cart.destroy if @cart.id == session[:cart_id] 
    session[:cart_id] = nil 
end 
respond_to do |format| 
    format.html { redirect_to root_path, notice: 'Your Cart is currently empty.' } 
    format.json { head :no_content } 
end 
end 

private 
    # Use callbacks to share common setup or constraints between actions. 
def set_cart 
    @cart = Cart.find(params[:id]) 
end 

# Never trust parameters from the scary internet, only allow the white list through. 
def cart_params 
    params[:cart] 
end 

def invalid_cart 
    logger.error "Attempt to access invalid cart #{params[:id]}" 
    redirect_to root_path, notice: 'Invalid cart' 
end 
end 

контроллер Line Items создать метод

def create 
product = Product.find(params[:product_id]) 
@line_item = @cart.add_product(product.id, params[:size]) 

respond_to do |format| 
    if @line_item.save 
    format.html { redirect_to customer_cart_path } 
    format.json { render :show, status: :created, location: @line_item } 
    else 
    format.html { render :new } 
    format.json { render json: @line_item.errors, status: :unprocessable_entity } 
    end 
end 
end 

Любая помощь будет оценена. Заранее спасибо!

ответ

0

Ранее работал на тележке я была такая же проблема, насколько я помню, он пришел из метода current_cart сидит в контроллере приложения

Я кончался изменить его к этому

def current_cart 
    @cart = Cart.find(session[:cart_id]) 
    rescue ActiveRecord::RecordNotFound 
    @cart = Cart.create 
    session[:cart_id] = @cart.id 
    @cart 
end 

также до @ cart.add _.... у меня есть вызов для метода в моем контроллере lineitems создать метод

@cart = current_cart 

Редактировать 1

это мой lineitems создать метод, который я думаю, что вам не хватает создание корзины, если нет ни

@lineitem = Lineitem.new(lineitem_params) 
@cart = current_cart 
item = Item.find(lineitem_params[:item_id]) 
@lineitem = @cart.addItem(item.id,@lineitem.quantity) 
+0

Спасибо за ваш ответ, но у меня нет метода 'current_cart' в приложении. контроллер. Я создал контроллер Customer, который наследуется от контроллера Carts (выше), вместо использования метода текущей корзины. Пробовал вызов '@cart = current_user.cart' метода в контроллере LineItems до' cart.add_product', но он тоже не работал. –

+0

Посмотрите на редактирование там –

+0

Я сделал это немного по-другому, я создаю корзину каждый раз, когда пользователь создан. Поэтому в моей модели пользователя у меня есть этот обратный вызов> 'after_create: default_cart' ' def default_cart self.create_cart 10 end' –

0

Я думаю, что этот код является неправильным в Customer::CartsController шоу действия

@cart = if current_user 
    current_user.cart ||= Cart.find_by(session[:cart_id]) 
    session[:cart_id] = nil if current_user.cart.purchased_at 
    end 

Это всегда будет делать @cart == nil

Я думаю, что это должно быть что-то вроде

@cart = if current_user 
    current_user.cart ||= Cart.find_by(session[:cart_id]) 
    session[:cart_id] = nil if current_user.cart.purchased_at 
    current_user.cart 
    end 

То есть, в последней части оператора if необходимо вернуть объект, который будет присвоен @cart

+0

Это тоже не работает. Выбрасывает 'неопределенный метод' add_product 'для nil: ошибка NilClass'. Ошибка в методе создания контроллера LineItems. Отредактированный вопрос с действием создания элемента управления LineItems. Таким образом, в корзине передается пустая переменная. –

1

Трудно точно сказать, что происходит здесь, не видя полный код. Например, вопрос в первую очередь связан с ошибкой, возникающей при попытке добавить продукт в корзину, но определение метода add_product не показано.

Я могу предложить пару советов, которые должны помочь. Во-первых, было трудно следовать методу showCustomer::CartsController. Я реорганизовал его, чтобы удалить ненужный вложенный оператор if и уменьшить количество условных выражений.

class Customer::CartsController < ApplicationController 
    before_action :authenticate_user! 

    def show 
    return unless current_user 

    current_user.cart ||= Cart.find(session[:cart_id]) 

    # if the cart has already been purchased, reset to a new cart 
    if current_user.cart.purchased_at 
     current_user.cart = Cart.create!(user_id: params[:id]) 
     session[:cart_id] = current_user.cart.id 
    end 

    @cart = current_user.cart 
    end 
end 

Во-вторых, при работе с ошибкой, как это, вы должны найти себе гораздо более конкретный вопрос (если не ответ на ваш вопрос).Чтобы прийти к такому конкретному вопросу, вам нужно отлаживать, чтобы точно выяснить, в чем проблема. Вы можете сделать это несколькими способами:

  1. Самый простой вариант - поместить в код некоторые «пробные» утверждения. Например, если вам нужно подтвердить, установлено ли значение purchased_at в действии на экране Customer :: CartsController, когда вы нажимаете для добавления в корзину, вы можете поместить в тело оператора if, например puts "purchased_at is set" . Выход будет отображаться на выходе сервера Rails, который вы можете наблюдать в другом окне во время взаимодействия с вашим сайтом в веб-браузере.

  2. Предпочтительным вариантом является использование отладчика. Я рекомендую pry, о котором вы можете найти и прочитать здесь: https://github.com/nixme/pry-debugger.

То, что вы должны пытаться делать с любым из этих методов, чтобы выяснить, где что происходит во время выполнения не соответствует вашим ожиданиям того, что ваш код должен был сделать, или то, что облегчило бы поведение, которое вы ожидаете, как Пользователь. В конечном счете, это часто приводит к изолированию определенной области кода, где вещи не имеют смысла, что делает вопрос намного проще.

Смежные вопросы