Reputation: 285
I'm trying to update my :completed field in rails 4 from the dashboard#home rather than the todos#edit. I have tried both PATCH and POST - none save, but with POST I don't get a 404 error when I click the checkbox, and with PATCH I do 'PATCH http://localhost:3000/dashboard 404 (Not Found)'. I'm not sure which one I have to use because I've seen some use POST and some PATCH.
My Route
patch 'todos/:id' => 'todos#completed'
My dashboard#home.html.erb
<%= check_box_tag 'todo[completed]', todo.id, todo.completed, data: { remote: true, url: url_for(controller: :todos, action: :completed, id: todo), method: "PATCH" }, id: todo.id %>
<%= label_tag todo.id, "COMPLETE", :class => 'strikethrough' %>
My Todo Complete Action
def completed
if @todo.update_attributes(:completed => params[:completed])
flash[:success] = "Wowzers."
redirect_to action: :show
else
flash.now[:error] = "Not so wowzers..."
render :new
end
end
My Rails Console as PATCH
Started PATCH "/todos/e3309e65a5f225ec696807ee1f5be3" for 80.193.7.142 at 2016-04-30 20:11:42 +0000
Cannot render console from 80.193.7.142! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by TodosController#update as JS
Parameters: {"todo"=>{"completed"=>"19"}, "id"=>"e3309e65a5f225ec696807ee1f5be3"}
Todo Load (0.2ms) SELECT "todos".* FROM "todos" WHERE "todos"."slug" = ? ORDER BY "todos"."id" ASC LIMIT 1 [["slug", "e3309e65a5f225ec696807ee1f5be3"]]
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
(0.1ms) begin transaction
DEPRECATION WARNING: You attempted to assign a value which is not explicitly `true` or `false` ("19") to a boolean column. Currently this value casts to `false`. This
will change to match Ruby's semantics, and will cast to `true` in Rails 5. If you would like to maintain the current behavior, you should explicitly handle the values
you would like cast to `false`. (called from block in update at /home/g9stuart4/recital/app/controllers/todos_controller.rb:46)
(0.0ms) commit transaction
Redirected to http://g9stuart4.koding.io:3000/dashboard
Completed 302 Found in 6ms (ActiveRecord: 0.4ms)
Started PATCH "/dashboard" for 80.193.7.142 at 2016-04-30 20:11:43 +0000
Cannot render console from 80.193.7.142! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
ActionController::RoutingError (No route matches [PATCH] "/dashboard"):
actionpack (4.2.5.1) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
web-console (2.3.0) lib/web_console/middleware.rb:20:in `block in call'
web-console (2.3.0) lib/web_console/middleware.rb:18:in `catch'
web-console (2.3.0) lib/web_console/middleware.rb:18:in `call'
actionpack (4.2.5.1) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
railties (4.2.5.1) lib/rails/rack/logger.rb:38:in `call_app'
railties (4.2.5.1) lib/rails/rack/logger.rb:20:in `block in call'
activesupport (4.2.5.1) lib/active_support/tagged_logging.rb:68:in `block in tagged'
activesupport (4.2.5.1) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (4.2.5.1) lib/active_support/tagged_logging.rb:68:in `tagged'
railties (4.2.5.1) lib/rails/rack/logger.rb:20:in `call'
actionpack (4.2.5.1) lib/action_dispatch/middleware/request_id.rb:21:in `call'
rack (1.6.4) lib/rack/methodoverride.rb:22:in `call'
rack (1.6.4) lib/rack/runtime.rb:18:in `call'
activesupport (4.2.5.1) lib/active_support/cache/strategy/local_cache_middleware.rb:28:in `call'
rack (1.6.4) lib/rack/lock.rb:17:in `call'
actionpack (4.2.5.1) lib/action_dispatch/middleware/static.rb:116:in `call'
rack (1.6.4) lib/rack/sendfile.rb:113:in `call'
railties (4.2.5.1) lib/rails/engine.rb:518:in `call'
railties (4.2.5.1) lib/rails/application.rb:165:in `call'
rack (1.6.4) lib/rack/lock.rb:17:in `call'
rack (1.6.4) lib/rack/content_length.rb:15:in `call'
rack (1.6.4) lib/rack/handler/webrick.rb:88:in `service'
/home/g9stuart4/.rvm/rubies/ruby-2.2.1/lib/ruby/2.2.0/webrick/httpserver.rb:138:in `service'
Any information is greatly appreciated.
Upvotes: 1
Views: 496
Reputation: 285
This is how I solved it.
My Controller
def completed
if @todo.update_attribute(:completed, [true, false])
flash[:success] = "Wowzers."
redirect_to dashboard_path
else
flash.now[:error] = "Not so wowzers..."
render :new
end
end
My Checkbox & Input.
<%= check_box_tag 'todo[completed]', todo.id, todo.completed, data: { remote: true, url: url_for(controller: :todos, action: :completed, id: todo), method: "POST" }, id: todo.id %>
<%= label_tag todo.id, "COMPLETE", :class => 'strikethrough' %>
My Routes
post 'todos/:id' => 'todos#completed'
I also rolled back my migration and added null: false and default: 0 on to my checkbox, as when I was tinkering around I kept getting null a lot which I believe to be part of the problem.
Anyhow, checkboxes now check and uncheck accordingly and update the database.
Upvotes: 1
Reputation: 2927
The custom route can be added to the todos resources route.
resources :todos do
member do
put 'completed'
end
end
Try running rake routes in the terminal to see what this produces.
The parameters hash is nested; the 'completed' value is nested within 'todo' so this line
if @todo.update_attributes(:completed => params[:completed])
should be
if @todo.update_attributes(:completed => params[:todo][:completed])
Are you sure you can add the url as data-attribute? I've not seen that before, which makes me think that is why you are getting the 404 error.
I would have thought you would need to surround the checkbox-tag with a form tag or use the button_to helper which you could then style to look like a checkbox. Font awesome has icons which you could use.
Upvotes: 0