Search code examples
scalacachingcontrollerplayframework-2.2

Play Framework - passing parameter to an action from another action in controller using Cache


I have a form that is submitted from view, before processing the form I checked the role, if everything is alright then I will insert/edit/delete/approve the data depends on which submit button is pressed, like below:

def input_form = withAccess { username => implicit request =>
        submitSOForm.bindFromRequest.fold (
           hasErrors = { form =>
                ....
            )},
            success = { userData =>
                if (Sales_Order.check(userData,"insert")) {
                    //using cache to pass the userData
                    Cache.set("userData", userData, 60)
                    if(request.body.asFormUrlEncoded.get("action")(0) == "Save" || request.body.asFormUrlEncoded.get("action")(0) == "Ask for Approval")
                        Redirect(routes.SalesOrders.insert(request.body.asFormUrlEncoded.get("action")(0)))
                    else
                        Redirect(routes.SalesOrders.approval("insert", request.body.asFormUrlEncoded.get("action")(0)))
                }
                else
                    Redirect(routes.SalesOrders.index).withSession(Security.username -> username, "timestamp" -> System.currentTimeMillis.toString).flashing(Flash() + ("invalid" -> "Inconsistent Input Data.") + ("insert" -> "block"))
            }
        )
    }

Everything works fine, I can get the userData either in insert or approval action method. However, I'm not sure using cache is the right choice. I imagine if there is a lot of request to input_form, then it will remove arbitrary data from the cache which is explained in the documentary.

An important point about the cache is that it behaves just like a cache should: 
the data you just stored may just go missing.

So, what I'm asking here is there any better way to passing that userData without using Cache ?


Solution

  • First thing is: you don't need to afraid cache's loose between requests - it's rather information that you shouldn't use it as a regular persistence layer.

    For main question: most probably Flash scope will be more suitable solution for this task.

    Remember that cache values will be available for other users, so if some user will perform similar action in the almost the same time (60 seconds) it will get value from others action - Flash as it's stored in the cookie will be individual.

    If you want to stay with cache - (i.e. in case that you want to store objects much bigger than 4kb) at least make sure that the cache keys contains some user specific, unique elements, like:

    Cache.set("userData"+currentUser.id, userData, 60)