Mathieu
Mathieu

Reputation: 4787

Prevent database action if Rails UJS (ajax) returns an Error or Timeout

I have a Rails UJS modal. When the user clicks the button it triggers an ajax call. I update certain database but I want that in case the rails ujs/ajax call timeouts or output an error, NOT to update these databases.

I feel I need to do this in the controller but I fail to find how.

HTML

<div id="zone" class="has-js">    
        <%= link_to image_tag(smallest_src_request),
              deal_modal_path,
              remote: true,
              class: "deal",
              alt: "loadin'" %>
      </span>
    </div>
  <% end %>
</div>

Controller

def deal_modal      
     # First Find UserDeal participation and update it
     find_and_update_selected_userdeal 
     # Actions on User
     update_user_profile 

     respond_to do |format|
       format.js
     end
end

So if the request timeouts, I display a classic message like 'Sorry too long...' which is fine but I noticed that despite this, I was actually doing all the controller actions and updating suerdeal and user tables.

I would like NOT to.

Could I use a before or after_filter and say if xhr status is error (I think it includes the case of "timeout"), then DO not do all these methods inside deal_modal method such as find_and_update_selected_userdeal and update_user_profile?

Is that possible ?

EDIT

some context

This issue is not related to the efficiency of the database call. Actually it's very fast (with a normal connection it's 150ms) but the app is mobile-intense and has some "business rules" (notably the number of time the user can see the content of the modal, that appears after he clicks the button, is limited to 3).

For example: the user is in a subway (and right now he has internet connection). He clicks on the link, which today updates the table User with user.total_nb_clicks (increment of 1) but then he enters a tunnel with almost no internet connection for 20 sec. I set in my app a Rails UJS timeout at 10 seconds for UX reasons (so that users do not think it's a bug). So the connection is so slow that the message in the Modal via Rails UJS is not the Result but sth like 'sorry timeout, try again'. But he is allowed only to try his luck 3 times so I should not have updated his column 'total_shots'. It's not his fault nor the app's fault there was a tunnel where he has only 5kb/sec of internet connection: he should still have the right to see 2 more modals/Results. It's a matter of real mobile usecase which can happen...

Upvotes: 1

Views: 364

Answers (1)

chrisandrew.cl
chrisandrew.cl

Reputation: 867

I saw a similar issue on how Heroku suggests you handle timeout in its environment, but I don't think it will work for your case scenario, because your timeout has nothing to do with long running server side processing.

When your controller finishes its job, there is no way to know that the http request has succeeded or not if the client failed to receive the response after the request. I believe it's because the HTTP Protocol is stateless.

That being said, you could try others approaches. The more straightforward I can think of is: persist information to show the same data to the user next time he try to visualize the content or when the connection is reestablished (not counting as a new click).

Upvotes: 1

Related Questions