重定向到控制器中另一个操作的最佳方法

时间:2014-11-26 16:17:18

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-4

我正在建造一个购物车"我希望允许用户更新购物车中的商品数量。我有一个购物车项目的删除链接,但用户可以从技术上将数量放到" 0"而不是点击删除按钮。所以"更新"我想检查@ cart.item.quantity == 0,如果是,那么只需重定向到控制器中的destroy动作。

对此最干净的解决方案是什么?这是我尝试过的,但它不起作用,我认为它不是最干净的方法......

在我的控制器中:

  def update
    if @cart_item.quantity == 0
      render action: :destroy
    else
      respond_to do |format|
        if @cart_item.update(cart_item_params)
          format.js#on { head :no_content }
        else
          format.json { render json: @cart_item.errors, status: :unprocessable_entity }
        end
      end
    end
  end

  def destroy
    @cart_item.destroy
    respond_to do |format|
      format.js
    end
  end

3 个答案:

答案 0 :(得分:1)

render不会执行该操作。最好只销毁update本身的购物车项目,而不是重定向到destroy动作

  def update
    if @cart_item.quantity == 0
      @cart_item.destroy
    else
      respond_to do |format|
        if @cart_item.update(cart_item_params)
          format.json { head :no_content }
        else
          format.json { render json: @cart_item.errors, status: :unprocessable_entity }
        end
      end
    end
  end

使用重定向:

def update
    if @cart_item.quantity == 0
      redirect_to action: :destroy, id: @cart_item.id
    else
      respond_to do |format|
        if @cart_item.update(cart_item_params)
          format.js#on { head :no_content }
        else
          format.json { render json: @cart_item.errors, status: :unprocessable_entity }
        end
      end
    end
  end

  def destroy
    @card_item = CartItem.find(params[:id]) #not sure if you are doing this elsewhere
    @cart_item.destroy
    respond_to do |format|
      format.js
    end
  end

答案 1 :(得分:0)

第一个答案是正确的,渲染不会执行操作。 Render获取控制器的当前状态,然后绘制视图。但是,如果您按原样调用其功能,则会出现问题。它将销毁该项,但不会呈现删除视图,因此,假设这是一个ajax调用,它将不会正确更新视图。

如果要执行控制器功能,您有两种选择:

  1. redirect_to your_destroy_action_path(@cart_item) - 我在这里不确定的一件事是,当您进行ajax调用然后使用重定向进行跟踪时,ajax的工作情况如何。我认为该操作仍将执行,但我不确定是否使用该间接级别正确处理了ajax视图代码。 (我想它会是,但从未尝试过自己编码。)

  2. 在您当前所在的地方调用destroy函数:

    渲染动作:: destroy

    所以它变成了:

  3. 
    
      def update
        if @cart_item.quantity == 0
          destroy
        else
          respond_to do |format|
            if @cart_item.update(cart_item_params)
              format.js#on { head :no_content }
            else
              format.json { render json: @cart_item.errors, status: :unprocessable_entity }
            end
          end
        end
      end
    
      def destroy
        @cart_item.destroy
        respond_to do |format|
          format.js
        end
      end
    
    
    

答案 2 :(得分:0)

我喜欢尽可能地保持控制器清洁。

如果我要开发它,我将创建一个Jquery函数来检查数量是否为零,如果是,则将表单操作更改为DELETE而不是PUT。