Let’s say you have a Todo app, with a model Todo that has a string title, and a boolean field, completed. We are going to use Stimulus to update our model remotely on the server when we check off the todo. And we’re going to use a nifty JavaScript API called fetch()
to make it all happen.
You can setup the Todo model with this command:
$ rails g scaffold Todo title:string completed:boolean --no-assets --no-helper --no-test-framework
So, in our Todos Controller, we’ll pull out all of our Todo records:
class TodosController < ApplicationController
def index
@todos = Todo.all
end
end
And in index.html.erb
, we’ll display the Todos, and put in the decorations that Stimulus will use:
<table>
<% @todos.each do |todo| %>
<tr data-controller="todo"
data-todo-update-url="<%= todo_path(todo) %>">
<td>
<input type="checkbox"
data-action="todo#toggle"
data-target="todo.completed"
<% if todo.completed %> checked <% end %> >
<%= todo.title %>
</td>
</tr>
<% end %>
</table>
Now, let’s create our todo_controller.js
and add the toggle method we specified above:
import { Controller } from "stimulus"
export default class extends Controller {
static targets = [ "completed" ]
toggle(event) {
// Code to follow
}
}
Inside the toggle(event)
function, start by getting the value of the checkbox, and put it into a FormData object:
let formData = new FormData()
formData.append("todo[completed]", this.completedTarget.checked);
Let’s post that data to the "update-url"
value we set on the Todo row. We’ll set the method to PATCH so that it gets routed to our todo#update
on our controller. The credentials and headers included ensure we send the session cookie and the CSRF protection token and prevent an ActionController::InvalidAuthenticityToken
error.
fetch(this.data.get("update-url"), {
body: formData,
method: 'PATCH',
credentials: "include",
dataType: "script",
headers: {
"X-CSRF-Token": getMetaValue("csrf-token")
},
})
We can take the Response object and verify that our request was successful. If there was an error, we’ll revert the checkbox change.
.then(function(response) {
if (response.status != 204) {
event.target.checked = !event.target.checked
}
})
Now, let’s go back to our ruby controller, and add our update method:
def update
@todo = Todo.find_by_id params[:id]
@todo.update todo_params
@todo.save
respond_to do |format|
format.js #add this at the beginning to make sure the form is populated.
end
end
private
def todo_params
params.require(:todo).permit(:title, :completed)
end
Now when we check or uncheck one of the check boxes, an AJAX request is sent to our Rails app, and Stimulus handles the response.
5 comments on “Updated Tutorial: How Do I Update My Model from a checkbox?”
[…] An updated version of this post can be found here: https://onrails.blog/2020/11/09/updated-tutorial-how-do-i-update-my-model-from-a-checkbox/ […]
[…] off the previous Todo example with this migration to add a priority to each […]
Hi.
Thanks for the tutorial – I followed your steps above exactly but I get an issue when checking the box:
ReferenceError: Can’t find variable: getMetaValue
I’m using Stimulus 2 if that makes a difference?
I’ve googled getMetaValue but can’t find anything! any help appreciated as I have a project I’m working on with checkboxes in a table just like your example and cannot get the values to update when I click them either the “Rails way” via an AJAX remote: true method in a check_box_tag or via your method and its driving me nuts!
Thanks.
Hi – Always the way, you post a comment and then find the solution 10 minutes later!
I’m assuming the getMetaValue function is one you wrote yourself and left out of the article to catch out lazy people like me ;-).
Found the following link:
https://guides.rubyonrails.org/working_with_javascript_in_rails.html#cross-site-request-forgery-csrf-token-in-ajax
which gave me the answer:
const token = document.getElementsByName(
“csrf-token”
)[0].content;
I swapped out your getMetaValue function for the token variable after using the above and it now works great.
Thanks again for the article – very useful.
Mark
[…] them with the newest tools available. Join me as we rebuild the first Stimulus Tutorial, and it’s updated version, “How do I Remotely Update My Model from a […]