2

I'm stuck worse than a Yugo in a ditch.

I added the changes which ultimately made this work below (marked as bold edits).

Background

  • Widgets have many Gadgets
  • The final td column in the table has check_box_tags to select individual Gadget records for deletion

Desired Behavior

  • User should be able to click "checkall" as well as individual checkboxes to select Gadgets one at a time
  • Clicking the "Delete Selected" button should delete checked records without refreshing the page

EDIT: Adding more specific details about what's not working

Observed Behavior

  • destroy_multiple method in gadgets_controller.rb is never being called
  • instead, the create method appears to be called

    Started POST "/widgets/1/gadgets" ...
    Processing by GadgetsController#create as JS
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"...=", "widget"=>{"gadget_ids"=>["all", "140", "139"]}, "widget_id"=>"1"}
    Widget Load (0.3ms) SELECT "widgets".* FROM "widget" WHERE "widget"."id" = $1 LIMIT 1 [["id", "1"]]
    Rendered gadgets/create.html.haml within layouts/application (1.1ms)
    Rendered layouts/_header.html.haml (0.2ms)
    Completed 200 OK in 36ms (Views: 19.0ms | ActiveRecord: 5.0ms)

I'm also unclear about this: {"gadget_ids"=>["all", "140", "139"]}.

"all" is the css id of 1 checkbox used to "checkall". In the checkbox.js.coffee file below, I attempt to remove the "all" value from the Array using javascript. When I log the Array to console, "all" is removed successfully. Yet it continues to be sent to the gadgets controller.

EDIT rails remote form populates the gadgets array for the POST request. just had to set it up correctly.

Models

widget.rb

class Widget < ActiveRecord::Base
  has_many :gadgets
  validates_presence_of :name
end

gadget.rb

class Gadget < ActiveRecord::Base
  belongs_to :widget
  validates_presence_of :widget_id
end

Gadgets Controller

class GadgetsController < ApplicationController
  include ApplicationHelper

  before_filter :get_widget
  before_filter :widget_gadgets, only: [ :index ]
  respond_to :json

  def json_widgets
    [ @widget, @gadgets ]
  end

  def index
    respond_with(json_widgets) do |format|
      format.json
      format.html
    end
  end

  def new
    @gadget = @widget.gadgets.new()
  end

  def create
    @gadget=@widget.gadgets.new(params[:gadget])
    if @gadget.save
      flash[:success] = "Gadget was successfully created"
      redirect_to widget_gadgets_path
    end
  end

  def destroy_multiple
    gadget_ids=(params[:gadget_ids])
    to_delete=[]
    gadget_ids.split(',').each do |gadget_id|
      to_delete.push(Gadget.find(gadget_id))
    end
    to_delete.each do |del|
      del.destroy()
    end
    flash.now[:success] = "Gadget Destroyed Successfully"
    respond_to do |format|
      format.html { redirect_to widget_gadgets_path(@widget) }
      format.json { render :json => to_delete.to_json }
    end
  end

  def destroy
    @gadget = gadget.find(params[:gadget_id])
    @widget.gadgets.destroy(@gadget.id)
    respond_to do |format|
      format.html { redirect_to(widget_gadgets_path) }
    end 
  end

  def get_widget
    begin
      @widget = Widget.find(params[:widget_id])
    rescue ActiveRecord::RecordNotFound
      render file: "public/404.html", status: 404
    end
  end

  private
  def widget_gadgets
    @widget=Widget.find(params[:widget_id])
    @gadgets=@widget.gadgets unless @widget.gadgets.nil?
  end      
end

routes.rb

I'm trying to use a collection do block. Is that the right way to implement a destroy_multiple route?

DestroyMultiple::Application.routes.draw do
  resources :widgets
  resources :gadgets, :only => [ :new, :create ]

  resources :widgets do
    resources :gadgets do
      collection do
        post :destroy_multiple
      end
    end
  end

  match "/:id" => 'widget#gadgets'
  root to: 'widgets#index'
end
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
hernamesbarbara
  • 6,850
  • 3
  • 26
  • 25
  • Maybe is better to use `accepts_nested_attributes_for`? – mikdiet Mar 24 '12 at 18:42
  • So what's the question? What doesn't work? – Frederick Cheung Mar 24 '12 at 21:40
  • Hi Frederick - it was totally unclear what the actual problem was! Sorry about that. I have added some more details. Thanks, – hernamesbarbara Mar 24 '12 at 22:30
  • Sorry for the long-winded question and for answering my own question. destroy_multiple widgets is now behaving properly, and I have included the changes I made above. The main problem was that I was trying to create my own javascript functions for stuff that Rails wants to do for you automatically via remote forms. – hernamesbarbara Mar 25 '12 at 02:04
  • You should take your solution and provide it as an answer – Azolo Mar 25 '12 at 03:44

1 Answers1

2

After getting this to work properly, I wanted to post the full solution.

Rather than type it all out here, please see the full application on GitHub.

While this solution works, I would be very interested to know how I can optimize the solution. Thanks again to those who helped!

https://github.com/hernamesbarbara/AJAX-Rails-Full-CRUD

hernamesbarbara
  • 6,850
  • 3
  • 26
  • 25