Jeff
Jeff

Reputation: 33

Rails routing error with custom put action

I have checkboxes on each of the items on my index page. I'm trying to implement a type of archiving feature where once a user is done with an item, they can check off the boxes of the records they are done with and then hit a button to submit the form which will toggle each item's "print" boolean to false.

My custom action "change_selected" should receive the id's of the records to change through the params and then call toggle on each of them.

The issue I.m having is that when I try to submit this form as it is, I get a routing error which says "No route matches [PUT] "/". Any help is appreciated. Or if there's a better way to do this, please let me know! Thank you!

# items_controller.rb

def index
 @items = Item.all.filter_by_status(params[:filter])
 @download = Item.all
 respond_to do |format|
  format.html
  format.csv {send_data @download.to_csv}
  format.json {render :json => @download}
 end
end

def change_selected
 params[:to_change].each do |i|
  Item.find_by_id(i).toggle(:print)
 end

 respond_to do |format|
  format.html {redirect_to items_path}
 end
end

le routes

Rails.application.routes.draw do
 root 'items#index'
 resources :items do
  collection do
   post :import
   put :change_selected
  end
 end
end

In my index view here's the form_for tag and then

<%= form_for change_selected_items_path, method: :put do %>
 <% item.each do |i| %>
 <%= check_box_tag "to_change[]", i.id %>
 <%= submit_tag "Change Selected" %>
<% end %>

rake routes:

               Prefix Verb   URI Pattern                  Controller#Action
              root GET    /                                items#index
      import_items POST   /items/import(.:format)          items#import
change_selected_items PUT    /items/change_selected(.:format) items#change_selected
             items GET    /items(.:format)                 items#index
                   POST   /items(.:format)                 items#create
          new_item GET    /items/new(.:format)             items#new
         edit_item GET    /items/:id/edit(.:format)        items#edit
              item GET    /items/:id(.:format)             items#show
                   PATCH  /items/:id(.:format)             items#update
                   PUT    /items/:id(.:format)             items#update
                   DELETE /items/:id(.:format)             items#destroy

Upvotes: 1

Views: 62

Answers (1)

alexanderbird
alexanderbird

Reputation: 4198

I believe the issue is your use of form_for - the docs say that it's for updating attributes of a model object. It's expecting a model name as a symbol or a model object as the first argument, but instead you're giving it a path as a string. It looks like it can't infer the path, so it's using the root path instead. If you're interested, you could read up on how rails infers the update path from the model symbol or object.

Instead, I suggest the vanilla form_tag helper which actually expects a path as the first argument.

<%= form_tag change_selected_items_path, method: :put do %>
  <% item.each do |i| %>
   <%= check_box_tag "to_change[]", i.id %>
  <% end %>
  <%= submit_tag "Change Selected" %>
<% end %> 

Upvotes: 3

Related Questions