命名空间和Simple_Form命中正确的控制器/动作

时间:2014-11-20 22:52:05

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

我在购物车页面上有一个表单来更新line_items。所以我正在更新的资源需要退出购物车控制器并进入line_items控制器...我正在使用以下表格......

<%= simple_form_for shifted_commerce_line_item_path(item), 
:url => {controller: 'line_items', action: 'update'} do |f| %>

我没有路线匹配...

No route matches {:action=>"update", :controller=>"shifted_commerce/line_items"}

事情是......我在控制器中有动作......

我会发布我的路线。

     shifted_commerce_line_items GET    /shifted_commerce/line_items(.:format)          shifted_commerce/line_items#index
                                 POST   /shifted_commerce/line_items(.:format)          shifted_commerce/line_items#create
  new_shifted_commerce_line_item GET    /shifted_commerce/line_items/new(.:format)      shifted_commerce/line_items#new
 edit_shifted_commerce_line_item GET    /shifted_commerce/line_items/:id/edit(.:format) shifted_commerce/line_items#edit
      shifted_commerce_line_item GET    /shifted_commerce/line_items/:id(.:format)      shifted_commerce/line_items#show
                                 PATCH  /shifted_commerce/line_items/:id(.:format)      shifted_commerce/line_items#update
                                 PUT    /shifted_commerce/line_items/:id(.:format)      shifted_commerce/line_items#update
                                 DELETE /shifted_commerce/line_items/:id(.:format)      shifted_commerce/line_items#destroy

如何让此表单在我的控制器中点击更新操作?

我们不是看到上述路线吗? PUT和PATCH都匹配/shifted_commerce/Line_items/:id ...我正在通过(项目)传递id ...

更新1 我还要补充一点,我在循环中运行此表单,因此可以编辑每个line_item。 @anything不是我想要传递给ID的路径...也是,我在推车行动中从推车控制器操作。不是line_item控制器,编辑操作。

更新2 如果我执行以下simple_form_for:

    <%= simple_form_for shifted_commerce_line_item_path(item), :url => {controller: 'line_items', action: 'create'} do |f| %>

它成功地将我带入了line_items控制器的创建操作。但是如果我做的话

    <%= simple_form_for shifted_commerce_line_item_path(item), :url => {controller: 'line_items', action: 'update'} do |f| %>

我收到路线错误。这是怎么回事?! 为什么它适用于创建但不适用于更新?我的控制器中有更新操作...

ShiftedCommerce :: LineItemsController

   class ShiftedCommerce::LineItemsController < ApplicationController
      before_action :set_line_item, only: [:show, :edit, :update, :destroy]
      before_action :set_line_item_item, only: [:show, :edit, :update, :destroy]

      # GET /line_items
      # GET /line_items.json
      def index
        @line_items = ShiftedCommerce::LineItem.all
      end

      # GET /line_items/1
      # GET /line_items/1.json
      def show
      end

      # GET /line_items/new
      def new
        @line_item = ShiftedCommerce::LineItem.new
      end

      # GET /line_items/1/edit
      def edit
      end

      # POST /line_items
      # POST /line_items.json
      def create
        @cart = current_cart
        # item is built from base_item, after finding associated product
          @base_item_id = params[:shifted_commerce_line_item][:base_item_id]
        get_item_id_from_base_item_params
          build_line_item

          ## Does a line item with the same itemt_id already exist in cart?
          if @line_item.exists_in_collect?(current_cart.line_items)
            #if so, change quantity, check if there's enough stock
              if  current_cart.where_line_item_with(@item_id).update_quantity(@line_item.quantity) == true
                @line_item.destroy
                redirect_to shifted_commerce_base_items_path
                flash[:success] = "Detected item In Cart,  Added Your Amount More to Quantity"
              else #otherwise there's not enough product in stock.
                redirect_to shifted_commerce_cart_path
                flash[:failure] = "Cannot Add To Cart, Not Enough In Stock"
              end
          else # This product isn't in the cart already let's save it!
            if @line_item.have_enough_item? == true # if there is enough stock, save
              if @line_item.save
                respond_to do |format|
                format.html { redirect_to shifted_commerce_base_items_path, 
                  :notice => "Added to Cart." }
                format.xml  { render :xml => @line_item,
                  :status => :created, :location => @line_item }
                end
              else
                format.xml  { render :xml => @line_item.errors,
                  :status => :unprocessable_entity }
              end
            else # not enough stock, not saved.
              redirect_to shifted_commerce_base_items_path
              if @line_item.item.stock_qty > 0
              flash[:failure] = "Sorry! We Only Don't Have Enough In Stock"
              else
              flash[:failure] = "Sorry! That Item Is Out Stock"
              end
            end 
          end
      end

      # PATCH/PUT /line_items/1
      # PATCH/PUT /line_items/1.json
      def update
      @line_item = ShiftedCommerce::LineItem.find(params[:id])
      raise
        @line_item.attributes = line_item_params
          if @line_item.over_order_cap? #is the quantity over maximum?
            flash[:error] = "Contact Us For Orders of This Size -- Quantity Set To Max"
            redirect_to cart_path
          else # quantity to change to not over maximum.
            if @line_item.have_enough_item? == true
               @line_item.update(line_item_params)
               #did they update quantity to 0?
                if @line_item.quantity <= 0
                   @line_item.destroy
                      flash[:success] = "Item Removed"
                      redirect_to :back
                else  
                      flash[:success] = "Itemed Updated"
                      redirect_to cart_path
                end
            else
              redirect_to cart_path
              flash[:failure] = "We Don't Have Enough In Stock.  Update Failed"
            end
          end
      end

      # DELETE /line_items/1
      # DELETE /line_items/1.json
      def destroy
        @line_item.destroy
        respond_to do |format|
          format.html { redirect_to line_items_url }
          format.json { head :no_content }
        end
      end

      private
        # Use callbacks to share common setup or constraints between actions.
        def set_line_item
          @line_item = LineItem.find(params[:id])
        end
        def set_line_item_item
          @line_item_name = @line_item.item.base_item
        end

        # Never trust parameters from the scary internet, only allow the white list through.
        def line_item_params
          params.fetch(:shifted_commerce_line_item, {}).permit(:item_id, :cart_id, :order_id, :quantity, :weight, :units)
        end
        def build_line_item
          @line_item = @cart.line_items.build(
            :item_id => @item_id,
            :order_id => nil,
            :weight => params[:shifted_commerce_line_item][:weight],
            :quantity => params[:shifted_commerce_line_item][:quantity]
            )
        end
        def get_item_id_from_base_item_params

          @item_id = ShiftedCommerce::Item.where(:base_item_id => @base_item_id).where(:size_id => params[:shifted_commerce_line_item][:size]).first.id
        end
    end

line_item.rb

   class ShiftedCommerce::LineItem < ActiveRecord::Base
      belongs_to :item
      belongs_to :cart
      after_create :set_order_weight#, :set_package_dimentions
      after_update :set_order_weight#, :set_package_dimentions
        #max capactiy here
        def have_enough_item?
          if self.item.stock_qty >= self.quantity
            return true
          else
            if self.quantity_was == nil
              return false
            else
            self.quantity = self.quantity_was
            self.save
            return false
            end
          end
        end
      def set_order_weight
         if 
           self.cart.nil?
         else 
           self.cart.total_weight = self.cart.line_items.to_a.sum {|item| (item.weight)*(item.quantity)}
           self.cart.save
         end
      end
        def over_order_cap?
            if self.quantity > 5
            self.quantity = 5
            self.save
            return true
            end
          return false
        end
        def update_quantity(qty)
          self.quantity += qty
          if self.have_enough_item? == true
          self.save
          end
        end
        def exists_in_collect?(items)
          items.each do |item|
            return true if self.item_id == item.item_id
          end
          return false
        end
        def set_order_total_units
          if 
            self.cart.nil?
          else 
            self.set_cart_units
            self.cart.total_units = self.cart.total_units
            self.cart.save
          end
        end
        def total_price
            item.base_item.price * quantity
        end
    end

的routes.rb

namespace :shifted_commerce do
    resources :line_items
    resources :items
    resources :base_items
    resource :cart, only: [:show, :update, :destroy] do
            resource :order, only: [:show, :create, :update, :edit, :new] 
        end
end

2 个答案:

答案 0 :(得分:2)

更改此设置并尝试:

<%= simple_form_for item, url: shifted_commerce_line_items_path(item), method: :put do |f| %>

根据您路线

更新

抱歉,它必须是post,但不是put,如下所示:

<%= simple_form_for item, url: shifted_commerce_line_item_path(item), method: :post do |f| %>

答案 1 :(得分:0)

尝试使用<%= simple_form_for ([:shifted_commerce, item]) do |f| %> <%= simple_form_for item, :url => shifted_commerce_line_item_path do |f| %>