Saturday, March 29, 2014

Paper_trail

As I mentioned in my last post, I was looking at using a gem called "paper_trail" to add a kind of "version control" to certain models in our Rails app. I was hoping to implement the undo function as part of a Rails flash message (so when the user clicked "Check-in", a flash message would appear at the top of the page saying that the progress was updated and asking the user if they wanted to undo the check-in if it was a mistake). However, since the progress-bar is in a partial and the update to the progress value is made through an ajax call, I could not get the flash message to return as part of the page's response headers (they got cleared out after the redirect_to call at the end of the method that updates the progress value). Based on the googling I did, I believe this is due to the fact that custom ajax calls do not explicitly retrieve flash message unless you tell them to, and the fact that the progress-bar was in a partial, which made it impossible to display the flash message in the view that was calling the partial. There may be some simple workaround for this issue, but so far, I have not found one.

Thus, I decided to try a different approach. I would use a button to perform the undo (which was probably better than the flash message method since I had to revert the versions of more than one model, which would have been difficult if I had just been using a link in the flash message, since the link would have accepted only one model as an argument). The button would only be display immediately after a checkin occurred and would only remain on the page for about 10 seconds before fading away (preventing the user for undoing an action at a much later point, which could have caused issues with the application). If the user clicked the undo button within that time, it would undo the check-in (reverting the progress and checkin counts) and update the display before fading away.

I had hoped that paper_trail would be able to perform the reverts without any extra updates on my part but, unfortunately, this was not the case. A typical call to revert to a pervious version for a given model (which is stored in a rails instance variable) looks like:

@instance_var.versions.last.reify
@instance_var.save

I had thought that this was working fine for the models that I was having to "undo", but it wasn't. For some reason, when I examined the server requests in the terminal, the paper_trail gem was only updating certain fields during the "rollback". For instance, in one model, it would revert to the previous progress value but not to the previous checkin count value. I am not sure why this is since all attributes of the model are accessible. The only reason I can think of for these issues is the fact that "has_many" and "belongs_to" relationships are not fully supported by paper_trail so I guess this may be influencing the way certain models are reverted based on whether or not they have these relationships. So, I had to do some manual updates to certain models after reverting, but this seemed to work. Now, when the user performs a check-in, they see the undo button as shown below (and the button will fade out after 10 seconds if the user does not click on it).


No comments:

Post a Comment