Resources

Download Source Code

Summary

# Terminal
rails new template --skip-javascript
bin/rails g scaffold products name color "price:decimal{8,2}" sku
bundle add faker
bundle add hotwire-rails
bin/rails hotwire:install

# db/seeds.rb
100.times do
  Product.create(
    name: Faker::Lorem.word,
    color: Faker::Color.hex_color,
    price: Faker::Commerce.price,
    sku: Faker::Number.number(10)
  )
end

# views/products/index.html.erb
<% @products.each do |product| %>
  <%= content_tag :tr, id: dom_id(product) do %>
    <td><%= product.name %></td>
    <td><%= product.color %></td>
    <td><%= product.price %></td>
    <td><%= product.sku %></td>
    <td><%= link_to 'Show', product %></td>
    <td><%= link_to 'Edit', edit_product_path(product) %></td>
    <td><%= link_to 'Destroy', product,
              data: {
                "turbo-method": :delete,
                controller: "confirmation",
                "confirmation-message-value": 'Are you sure?',
                action: "confirmation#confirm"
              } %></td>
  <% end %>
<% end %>

# OPTIONS 1 - products_controller.rb
include ActionView::RecordIdentifier

def destroy
  @product.destroy
  respond_to do |format|
    format.html { redirect_to products_url, notice: "Product was successfully destroyed." }
    format.json { head :no_content }
    format.turbo_stream { render turbo_stream: turbo_stream.remove(dom_id(@product)) }
  end
end

# OPTION 2 - products_controller.rb
def destroy
  @product.destroy
  respond_to do |format|
    format.html { redirect_to products_url, notice: "Product was successfully destroyed." }
    format.json { head :no_content }
    format.turbo_stream {}
  end
end

# OPTION 2 - views/products/destroy.turbo_stream.erb
<%= turbo_stream.remove(dom_id(@product)) %>

# app/assets/javascripts/controllers/confirmation_controller.js
import { Controller } from "stimulus"

export default class extends Controller {
  static values = { message: String }

  confirm(event) {
    if (!(window.confirm(this.messageValue))) {
      event.preventDefault()
      event.stopImmediatePropagation()
    }
  }
}