Using Turbo with Rails seems to be returning old/cached value of AR object

Hey!

I’m encountering weird behaviour with Turbo streams using Rails and I’m out of ideas what’s going on as I’ve never seen such a behaviour.

I have this simple one field form for changing a note. Wrapped in a turbo frame, it either displays the note and edit link, or form to simulate inline edit. My update action is also pretty simple.

The problem is, when I update the AR object, it has updated value after order.update, it has updated value in format block, but network response in the browser has old value => it seems like nothing changed. Magic happens when I add significant sleep on Rails side. For some reason, browser cancels first submit request and second submit request has updated value.

  def update_note
    order = Order.find(params[:id])
    order.update(user_edit_params)

    respond_to do |format|
      format.turbo_stream do
        order.reload
        sleep 0.05
        pp order.comment
        render turbo_stream: turbo_stream.replace(
          :order_note,
          partial: 'orders/order_note',
          locals: { order: order },
        )
      end
     ...

You can notice reload, sleep and pp calls as I’m trying to debug the issue.

Is there some kind of cache I’m unaware of? Rails log doesn’t suggest that it’s using any cache for template/partial rendering.

I’m running latest version of turbo-rails with Rails 7.2.x. I’ll appreciate any idea. It feels like I’m missing something very obvious even while writing this question :smile: but I’m out of ideas.

What happens if you make the request with curl? This would help narrow down whether it’s a browser issue (you may need to disable csrf protection). Worth trying another browser also.

@jch sorry, should’ve mentioned that. I’ve already tried multiple browsers and now also CURL request. No change.

Could you paste the output of your curl? Be sure to include the turbo stream header so it’s going through the right block Turbo Handbook

Of course. I’ll also add full CURL command except cookies.

Everything seems all right to me. Output is correct TurboStream response, just including old DB value. You can see that comment payload is aaa but the response includes old aaabbb value.

curl 'http://localhost:3000/orders/102/update_note' \
        -H 'Accept-Language: en-US,en;q=0.9' \
        -H 'Connection: keep-alive' \
        -H 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' \
        -H 'DNT: 1' \
        -H 'Origin: http://localhost:3000' \
        -H 'Referer: http://localhost:3000/orders/102' \
        -H 'Sec-Fetch-Dest: empty' \
        -H 'Sec-Fetch-Mode: cors' \
        -H 'Sec-Fetch-Site: same-origin' \
        -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36' \
        -H 'accept: text/vnd.turbo-stream.html, text/html, application/xhtml+xml' \
        -H 'sec-ch-ua: "Not?A_Brand";v="99", "Chromium";v="130"' \
        -H 'sec-ch-ua-mobile: ?0' \
        -H 'sec-ch-ua-platform: "macOS"' \
        -H 'x-csrf-token: VcrSRq8AI10aRbtbVX5dmGO-Q1BaHMIhGk4zOFXp3RtilkWOLR1kk5tNxuWuc6nUjBo1FjfNOy5w47iAXaJw8Q' \
        -H 'x-turbo-request-id: dcceb09c-1a5e-4da2-a0c6-cabb2b9c6c70' \
        --data-raw '_method=patch&authenticity_token=dSK37yPme_-SH4jUogkVM85S0MgOdowGAjCFwkxuZ7JCfiAnofs8MRMX9WpZBOF_IfamjmOndQlonQ56RCXKWA&order%5Bcomment%5D=aaa&commit=Aktualizovat+Objedn%C3%A1vka'


<turbo-stream action="replace" target="order_note"><template><!-- BEGIN app/views/orders/_order_note.html.slim -->
<turbo-frame id="order_note"><a href="/orders/102/edit_note"><span class="fa fa-pencil"></span> Upravit</a><div id="comment">aaabbb</div></turbo-frame><!-- END app/views/orders/_order_note.html.slim -->
</template></turbo-stream>

Finally found it :man_facepalming: Was mixing local order and instance @order variable in the partial I was rendering.