grails service with different scopes for persistence
Asked Answered
A

2

6

I have one domain, in that domain more than 25 members are there. This members value will come from one form. But it feels bad to fill those too much fields. So I thought dividing input form into different stages.

I've made a class called FormObject that has fields for ALL the input needed. The problem is theres no way to pass this object between pages.

I was thinking maybe a service with the scope of session would allow me to keep a reference to a FormObject and just call a method from the service to get it again.

<g:set var="formService" value="${new FormService()}" /> 

class FormService{
    static transactional = false
    static scope = "session"

    FormObject myObject = new FormObject()

    def resetForm(){
        myObject=new FormObject()
    }

    def getForm(){
        return myObject
    }
}

and used that into GSP like

<g:set var="myForm" value="${formService.getForm()}" />

However the data doesn't persist between pages.

It does persist if I define the myObject property as static, but I'm worried that when this hits production, the myObject will be shared across all users.

Can anyone confirm what would happen if I made it static? Would each session have a static form object or would there only be one static form object?

Autogamy answered 1/2, 2013 at 18:10 Comment(0)
A
2

I got the solution....

The first approach is close, except that you're creating a new instance instead of getting it as a Spring bean, so the fact that it's session-scoped isn't coming into play. In general if you have workflows that span more than two pages, you should look at WebFlow, but that might be a bigger solution than you need.

I would skip the service wrapper and just store the object in the session. The risk here is that you can end up polluting your sessions with objects if something happens and you don't remove them, so you should handle that.

In the first controller action make sure the object is there:

def action1 = {
   ... regular work
   session.formObject = new FormObject()
   // return model, e.g.
   [foo: bar]
}

and in GSPs you can refer it

${session.formObject}
Autogamy answered 1/2, 2013 at 18:10 Comment(3)
Why you're answering your own question like as you're talking to another person? lol.Ardoin
@lucke84, this question important and new for knowledge to grails developer.Autogamy
It's a good thing you shared your solution, I'm just wondering why you didn't just say "I solved it this way" instead of "You have to do it this way".Ardoin
G
1

I probably would take another approach and provide the form object through the model via the controller - all persistance issues would also be done through the controller, so that your first approach will work as expected...

function showForm() {
  render[view: 'view', model: [serviceForm: formService.form]]
}

function persistForm(MyCommand cmd) {
  // check cmd for errors
  if(cmd.hasErrors()) {
    // return the MyCommand object for error yielding
    render(view: 'view', model: [cmd: cmd]]
  }
  // persist cmd fields to formService.form object
  formService.form.field = cmd.field
}

this should work as expected

Glassware answered 5/2, 2013 at 10:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.