如何正确路由嵌套资源销毁动作?

时间:2016-01-24 21:57:53

标签: ruby-on-rails nested-attributes nested-routes

所以我有一个嵌套资源属于发票的物品,我试图通过在创建/编辑发票时删除它来销毁物品。

我可以删除记录,但是当我这样做时,记录会从数据库中删除,但页面不会刷新或转到任何地方,但是当我手动刷新页面时,记录将被删除。我注意到在我的控制台中我得到了1500内部服务器错误,并且由于此错误而发生这种情况。

为嵌套资源编写destroy操作的最佳方法是什么?

ActionController::UrlGenerationError at /invoices/100/items/247
===============================================================

> No route matches {:action=>"index", :controller=>"items", :id=>"247", :invoice_id=>"100"}

app/controllers/items_controller.rb
 ``` ruby
 44     end
 45   
 46     def destroy
 47       @item = Item.find(params[:id])
 48       @item.destroy
>49       redirect_to :action => 'index'
 50     end    

这是我的佣金路线

$ rake routes
Prefix Verb   URI Pattern                               Controller#Action
item_index GET    /item/index(.:format)                     item#index
item_show GET    /item/show(.:format)                      item#show
item_new GET    /item/new(.:format)                       item#new
item_edit GET    /item/edit(.:format)                      item#edit
invoice_item DELETE /invoices/:invoice_id/items/:id(.:format) items#destroy
invoices GET    /invoices(.:format)                       invoices#index
         POST   /invoices(.:format)                       invoices#create
new_invoice GET    /invoices/new(.:format)                   invoices#new
edit_invoice GET    /invoices/:id/edit(.:format)              invoices#edit
 invoice GET    /invoices/:id(.:format)                   invoices#show
         PATCH  /invoices/:id(.:format)                   invoices#update
         PUT    /invoices/:id(.:format)                   invoices#update
         DELETE /invoices/:id(.:format)                   invoices#destroy
    root GET    /    

完整物品控制器

class ItemsController < ApplicationController
  def index
    @items = Item.all
  end

  def show
    @invoice = Invoice.find(params[:invoice_id])
    @item = Item.find(params[:id])
  end

  def new
    @item = Item.new
  end

  def edit
    @item = Item.find(params[:id])
  end

  def create
    @item = Item.new(item_params)

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

  def update
    @item = Item.find(params[:id])
    respond_to do |format|
      if @item.update(item_params)
        format.html { redirect_to @item, notice: 'Item was successfully updated.' }
        format.json { render :show, status: :ok, location: @item }
      else
        format.html { render :edit }
        format.json { render json: @i[item].errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @item = Item.find(params[:id])
    @item.destroy
    redirect_to :action => 'index'
  end

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

    # Never trust parameters from the scary internet, only allow the white list through.
    def item_params
      params.require(:item).permit(:item_name, :item_description, :item_cost, :item_quantity, :item_price, :destroy)
    end

end

这是我的表格

<%= simple_form_for(@invoice) do |f| %>
<%= f.input_field :company, class: "form-control", id: "1" %>

<%= f.simple_fields_for :items do |h| %>
    <div class="duplicatable_nested_form">
      <h4>New item</h4>
        <p>Name</p>
          <%= h.input_field :item_name, class: "form-control" %>
          <p>Description</p>
          <%= h.input_field :item_description, class: "form-control" %>
          <p>Cost</p>
          <%= h.input_field :item_cost, class: "form-control cost", id: "price" %>
          <p>Quantity</p>
          <%= h.input_field :item_quantity, class: "form-control qty", id: "quantity" %>
              <td></td>

           <% if h.object.new_record? %>
           <%= link_to 'Remove', '', :remote => true, :class => 'destroy_duplicate_nested_form' %>
           <% else %>
           <%= link_to 'Remove', invoice_item_path(@invoice, h.object), :method => :delete, :remote => true, :class => 'destroy_duplicate_nested_form' %>
           <%= h.input :id, as: :hidden %>
               <% end %>
  <P class="price_td"><span class="price">650.00</span><span class="subtotal_currency"></span></P>


  <% end %>
 </div>

<%= link_to 'Add Another Item', '', :class => 'duplicate_nested_form' %>
<%= f.button :submit, 'Submit Payment', class: 'btn btn-warning btn-sm', id: "submit_invoice" %>

这是我的nested_forms.js.coffee

jQuery ($) ->

    if $('.duplicatable_nested_form').length

      nestedForm = $('.duplicatable_nested_form').last().clone()
                              .find("input:text").val("").end()

      $(".destroy_duplicate_nested_form:first").remove()

      $('.destroy_duplicate_nested_form').on 'click', (e) ->
        $(this).closest('.duplicatable_nested_form').slideUp().remove()

      $('body').on 'click','.destroy_duplicate_nested_form', (e) ->
        $(this).closest('.duplicatable_nested_form').slideUp().remove()

      $('.duplicate_nested_form').click (e) ->
        e.preventDefault()
        console.log("this is the click");
        lastNestedForm = $('.duplicatable_nested_form').last()
        newNestedForm  = $(nestedForm).clone()
        formsOnPage    = $('.duplicatable_nested_form').length
        $('#updatedAt').fadeOut('new')
        $(newNestedForm).find('label').each ->
          oldLabel = $(this).attr 'for'
          newLabel = oldLabel.replace(new RegExp(/_[0-9]+_/), "_#{formsOnPage}_")
          $(this).attr 'for', newLabel

        $(newNestedForm).find('select, input').each ->
          oldId = $(this).attr 'id'
          newId = oldId.replace(new RegExp(/_[0-9]+_/), "_#{formsOnPage}_")
          $(this).attr 'id', newId

          oldName = $(this).attr 'name'
          newName = oldName.replace(new RegExp(/\[[0-9]+\]/), "[#{formsOnPage}]")
          $(this).attr 'name', newName

        $( newNestedForm ).insertAfter( lastNestedForm )

我的路线

Rails.application.routes.draw do

  get 'item/index'
  get 'item/show'
  get 'item/new'
  get 'item/edit'

  resources :invoices do 
    resources :items, only: :destroy
  end

  # The priority is based upon order of creation: first created -> highest priority.
  # See how all your routes lay out with "rake routes".

  # You can have the root of your site routed with "root"
   root 'invoices#index'

1 个答案:

答案 0 :(得分:1)

_path

中使用redirect
def destroy
  @item = Item.find(params[:id])
  @item.destroy
  redirect_to item_index_path
end

<强>顺便说一句

非常奇怪的溃败:

invoice_item DELETE /invoices/:invoice_id/items/:id(.:format) items#destroy

项目控制器中的invoice_item?破坏?