This blog keeps a record of ideas, notes, and documentation, in chronological
order. The writings are often not polished, and may contain errors here
and there, but I like to keep them here for future reference.
This page publishes the most recent blog posts.
To view all posts in a single page,
go to the archive.
Confirm delete a record
Deleting a record from a list (for example in the index view) can be performed using the button_to method.
This method will create an html form, with a few elements inside of it: a
button and two hidden input elements.
One hidden element is the authenticity token that makes sure the form is safe.
The form itself will make a POST request to /posts/:id with the id of the
record to delete.
To prevent accidental removal of records, we can add a confirmation modal dialog
with the data-turbo-confirm attribute on the form element.
If the user cancels the dialog, the form will not be submitted.
Here’s how to add the data-turbo-confirm dialog to the form, from inside the
button_to method:
<%= button_to "Delete", post_path(post), method: :delete, form: {data: {turbo_confirm: "This post will be deleted immediately. Do you want to continue?"}}, class: "inline-block underline text-indigo-600" %>
Rails default sorting
The default_scope method in a model lets us sort records in a default sorting
order, like so:
class Post < ApplicationRecord default_scope order(created_at: :desc)end
default_scope is used to set any default on operations on a model. Here’s
another example:
default_scope where(deleted_on: nil)
Even though default_scope is useful in certain circumstances, it has its
drawbacks, and it’s probably better to avoid using it in favor of setting
explicit scopes instead.
Here’s an example:
class PostsController < ApplicationController def index @posts = Post.order(created_at: :desc) endend
Apply custom styles to the content by adding a class to a content container (in
this example a div with class text-content) and by adding TailwindCSS styles
under that class.
Install the library using importmap with this command:
$ bin/importmap pin @stimulus-components/rails-nested-form> Pinning "@stimulus-components/rails-nested-form" to > vendor/javascript/@stimulus-components/rails-nested-form.js> via download from https://ga.jspm.io/npm:@stimulus-components/[email protected]/dist/stimulus-rails-nested-form.mjs> Pinning "@hotwired/stimulus" to vendor/javascript/@hotwired/stimulus.js> via download from https://ga.jspm.io/npm:@hotwired/[email protected]/dist/stimulus.js
This action changes config/importmap.rb like so:
diff --git a/config/importmap.rb b/config/importmap.rb-pin "@hotwired/stimulus", to: "stimulus.min.js"+pin "@hotwired/stimulus", to: "@hotwired--stimulus.js" # @3.2.2+pin "@stimulus-components/rails-nested-form", to: "@stimulus-components--rails-nested-form.js" # @5.0.0
It also adds the following files to vendor/javascript:
This will generate `app/javascripts/controller/nested_form_controller.js`
Remove all the generated code in the file and add the following code, copied from the
documentation
under Extending Controller.
// app/javascripts/controller/nested_form_controller.jsimport NestedForm from "@stimulus-components/rails-nested-form"export default class extends NestedForm { connect() { super.connect() console.log("Do what you want here.") }}
3. Update the form
In the form, add some data attributes required by the nested form controller:
If we load the page with the form at this point
http://localhost:3000/pathways/new we should see in the browser console the output of the
console.log command that we put in the nested form controller. This confirms
the controller is accessed correctly.
// app/javascripts/controller/nested_form_controller.js ... console.log("Do what you want here.") ...
Inside the form, add a <template> element that wraps the nested fields. Adjust
the template to add the new object to add Step.new, and a child_index
attribute with the value of NEW_RECORD.
Inside the nested fields, render a Rails partial with the actual fields needed, shown
below.
<% if object.errors.any? %> <section class="bg-orange-200 p-8 my-8 mx-auto"> <h2> Your form could not be saved. </h2> <h3> Please correct the following <%= pluralize(object.errors.size, "error") %>: </h3> <ul> <% object.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </section><% end %>
Styling the .field_with_errors class in the main application.css file: