1

I just updated my Rails 6 app to Rails 7 and have problems updating my :patch and :delete links to Turbo.

For example, in one of my views I have this link...

 link_to("Mark as sent", status_url(quote), :data => {:'turbo_method' => :patch})

... which is handled by this controller:

class StatusController < ApplicationController

  def update
    @quote = Quote.find(params[:id])
    @quote.send_it! # Should trigger AASM
    flash[:notice] = "Quote marked as sent."
    redirect_to edit_quote_path(@quote)
  end

end

In the model I am using AASM as a state machine:

class Quote < ApplicationRecord

  include AASM
     
  aasm :column => "status" do
    state :draft, :initial => true
    state :inquired
    state :sent
    state :downloaded
    state :accepted
    state :rejected

    event :send_it do
      transitions :from => [:draft, :inquired], :to => :sent
    end

    ...

    event :reset_it do
      transitions :from => [:inquired, :sent, :downloaded, :accepted, :rejected], :to => :draft
    end

  end

end

The problem is that the state machine does not get triggered when I hit the link. The flash message and the redirect work but the state is not changed in the database. When I replace @quote.send_it! with @quote.update_column(:status, "sent")it works, however.

Can anybody tell me what I'm missing here?

Tintin81
  • 9,821
  • 20
  • 85
  • 178
  • I don't see anywhere in AASM that offers you dynamic methods like `:mark_as_#{status}`. I'm assuming this used to work, but I don't understand why. – Chiperific Aug 12 '22 at 16:20
  • Couldn't you just create a method like `@quote.mark_as(status)` that does what you want? – Chiperific Aug 12 '22 at 16:21
  • @Chiperific, maybe my initial post was a little misleading. I just updated my code above. – Tintin81 Aug 12 '22 at 18:06

2 Answers2

1

I don't quite see how turbo is related. Except that I think your redirect isn't actually working:

Redirected to http://127.0.0.1:3000/quotes/1/edit
Completed 302 Found in 18ms (ActiveRecord: 4.3ms | Allocations: 7265)

Started PATCH "/quotes/1/edit" for 127.0.0.1 at 2022-08-12 
 
ActionController::RoutingError (No route matches [PATCH] "/quotes/1/edit"):
# NOTE: ^ not quite a redirect

#       v but it doesn't show on a page, it just refreshes the current one.
Started GET "/quotes" for 127.0.0.1 at 2022-08-12 17:51:28 -0400

#       and if the current page were /quotes/1/edit then it would look like
#       redirect worked, but I was submitting from /quotes.

Update your controller to actually show any errors:

def update
  @quote = Quote.find(params[:id])

  # NOTE: if transition fails, `send_it!` returns `false` 
  #       (or raises an error for invalid transitions)
  #       when you run `@quote.update_column(:status, "sent")`
  #       validations and state machine are not triggered and it works.
  if @quote.send_it!
    flash.notice = "Quote marked as sent."
  else
    flash.notice = @quote.errors.full_messages.join(", ")
  end

  respond_to do |format|
    # in case you want add a stream response later
    # format.turbo_stream { # TODO }
    format.html { redirect_to edit_quote_path(@quote), status: :see_other }
    # NOTE: Redirect as a GET request instead of PATCH ^
  end
end

Or just add whiny_persistence flag and check the logs, this will raise validation errors:

aasm column: :status, whiny_persistence: true do
Alex
  • 16,409
  • 6
  • 40
  • 56
  • Thanks for your help. Your answer was an eye-opener to me since Turbo was indeed not to blame here. The `status` attribute could simply not be toggled because the record was not valid. Therefore, the status change triggered by AASM kept failing. I fixed that and it works now. Thanks for showing me how to debug this issue. – Tintin81 Aug 15 '22 at 09:36
0

Not sure where you got the mark_as_ from, change that to @quote.aasm.fire! status.

Edit

Sorry, not status, needs to be the event, just use the right event.

smathy
  • 26,283
  • 5
  • 48
  • 68
  • OK, I tried `@quote.aasm.fire!(:send_it)` but that doesn't work either. I also simplified my initial post above. So if you have another idea, please let me know. – Tintin81 Aug 12 '22 at 18:11
  • So when you say it "doesn't work", what does that mean? You have a quote in :draft or :inquired state, and you run this on it, and you get redirected, see the flash message, but the quote is still in the same state? – smathy Aug 12 '22 at 19:28
  • Precisely. The redirect + flash message works but the state remains in „draft“. – Tintin81 Aug 12 '22 at 20:05
  • And the same code works in the rails console? (For the same quote) – smathy Aug 12 '22 at 23:46