ruby on rails - How to properly route a nested resources destroy action? -


so have nested resource items belonging invoices , trying destroy items deleting them when invoices created/edited.

i can delete records when record gets deleted form db page not refresh or go anywhere, when refresh page manually record removed. noticed in console getting 1500 internal server error` , thats happening because of error.

what best way write destroy action nested resources?

actioncontroller::urlgenerationerror @ /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     

and here rake routes

$ rake routes prefix verb   uri pattern                               controller#action item_index    /item/index(.:format)                     item#index item_show    /item/show(.:format)                      item#show item_new    /item/new(.:format)                       item#new item_edit    /item/edit(.:format)                      item#edit invoice_item delete /invoices/:invoice_id/items/:id(.:format) items#destroy invoices    /invoices(.:format)                       invoices#index          post   /invoices(.:format)                       invoices#create new_invoice    /invoices/new(.:format)                   invoices#new edit_invoice    /invoices/:id/edit(.:format)              invoices#edit  invoice    /invoices/:id(.:format)                   invoices#show          patch  /invoices/:id(.:format)                   invoices#update          put    /invoices/:id(.:format)                   invoices#update          delete /invoices/:id(.:format)                   invoices#destroy     root    /     

full items controller

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 |format|       if @item.save         format.html { redirect_to @item, notice: 'item 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 |format|       if @item.update(item_params)         format.html { redirect_to @item, notice: 'item 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 share common setup or constraints between actions.     def set_item       @item = item.find(params[:id])     end      # never trust parameters scary internet, allow white list through.     def item_params       params.require(:item).permit(:item_name, :item_description, :item_cost, :item_quantity, :item_price, :destroy)     end  end 

here form

<%= simple_form_for(@invoice) |f| %> <%= f.input_field :company, class: "form-control", id: "1" %>  <%= f.simple_fields_for :items |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 item', '', :class => 'duplicate_nested_form' %> <%= f.button :submit, 'submit payment', class: 'btn btn-warning btn-sm', id: "submit_invoice" %> 

and here 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 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 ) 

my routes

rails.application.routes.draw    'item/index'   'item/show'   'item/new'   'item/edit'    resources :invoices      resources :items, only: :destroy   end    # priority based upon order of creation: first created -> highest priority.   # see how routes lay out "rake routes".    # can have root of site routed "root"    root 'invoices#index' 

use _path in redirect

def destroy   @item = item.find(params[:id])   @item.destroy   redirect_to item_index_path end 

btw

very strange rout:

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

invoice_item in item controller? destroy?


Comments