Home > OS >  Accessing instance variable or Active Record via a Stimulus Controller in Rails
Accessing instance variable or Active Record via a Stimulus Controller in Rails

Time:12-15

I am looking to use a delete link on a row of todos destroy the todo on click.

I'm using stimulus, but can't seem to get the stimulus controller to access the @todos instance variable (already on the HTML page via the std rails controller). Alternatively, I can't seem to access Active Record at all from the Stimulus controller for things like Todo.destroy().

HTML.ERB:

  <div data-controller="complete">
<% @todos.each_with_index do |todo, index | %>
<div>
  <div>
    <label><%= todo.name %></label>
  </div>
  <a href="#" data-action="click->complete#delete" data-id=<%= todo.id %> >Delete</a>
</div>
<% end %>

In the stimulus controller:

  get id() {
    return event.currentTarget.dataset.id;
  }

  delete() {
    console.log("delete id:", this.id)
    // console.log("@todos", @todos) #fails
    // Todos.find(this.id).destroy #fails
    // @todos.find(this.id).destroy #fails
  }

Thanks for any insight!

CodePudding user response:

You just seem to completely missunderstood both what Stimulus is and what its used for and other key tenants of web development like the difference between the server and client side code.

Stimulus is a low level framework for tying javascript to data attributes in in your markup. It forms the foundation of Turbo. Its not magic unicorn dust that makes anything on the server availble in client side.

It does not replace the server side code which is actually used to Create, Read, Update and Destroy (CRUD) your data.

What you actually want here is just a button and a Rails controller:

<% @todos.each do |todo| %>
  # ...
  <%= button_to 'Delete todo', todo, method: :delete %>
<% end %>
class TodosController < ApplicationController
  before_action :set_todos, only: [:show, :edit, :update, :destroy]

  # ...

  # DELETE /todos/1
  def destroy
    @todo.destroy
    redirect_to action: :index
  end

  private

  def set_todo
    @todo = Todo.find(params[:id])
  end
end
  • Related