Home > Blockchain >  Rails update action does not modify model attribute, no error thrown
Rails update action does not modify model attribute, no error thrown

Time:07-14

My Rails 7 app uses the following models:

  • Batch model, has_many tasks
  • Task model, belongs_to a batch

Resources are nested as follows:

resources :batches do
  resources :tasks
end

The Task model has a completed_at field, which is nil by default, and which we want to update to DateTime.now when the task is completed.

The goal is to display tasks in the task index view, with a do/undo button depending on whether the task has already been completed or not (a task can be completed, and then uncompleted, and in that case we want to reset the value of completed_at to nil).

To determine whether a task has been completed, the following method has been added to the Task model:

def completed?
  !completed_at.nil?
end

In the task index view, tasks are displayed as follows:

<% @tasks.each do |task| %>
  <li>
    <div>
      <%= do_or_undo(@batch, task) %>
      <%= task.title %>
    </div>
  </li>
<% end %>

The do_or_undo(batch, task) method is defined as a task view helper in tasks_helper.rb, as follows:

def do_or_undo(batch, task)
  unless task.completed?
    button_to "Do", batch_task_path(batch, task), data: { turbo_method: :update }
  else
    button_to "Undo", batch_task_path(batch, task), data: { turbo_method: :update }
  end
end

In the tasks index view, the correct variation of the do or undo button is display when first loading the view, however, when clicking on that button, the value of the completed_at field is not updated, neither to nil when clicking on undo, nor to DateTime.now when clicking on do — and the text of the button is not updated (neither to do when clicking undo, nor to undo when clicking do).

No error is being thrown, which is the reason why I am unsure where to go next to investigate and fix the issue.

Two questions:

  1. Why is this not working?
  2. Is there a better way to implement this, maybe with a checkbox instead of a button (using jQuery or Hotwire)?

CodePudding user response:

The problem here is the turbo_method attribute this has to be one of

get, post, put, delete

link_to "Update", your_url, data: { turbo_method: :put }

for your case you should use the put method in your link if you want to make a request to the update action. Then inside of the controller action you will want to redirect the user to update the page or respond with a turbo_stream to do so

  • Related