apache / apache/grails-core

Grails 3 unable to bind request parameter to multilevel command objects

Open
#11,259 12 comments 0 reactions 0 assignees View on GitHub
Dominant language
Groovy
Stars
2.9k
Forks
975
Avg merge
1d 22h
Merged PRs (30d)
92

Description

We are trying to post form data as

> "student.id=1&courses[10].course.id=10"

The command object classes we are trying to bind are as below ...

```
class StudentEnrollmentCmd {
MyStudent student
Map courses;
}
class MyStudent {
Long id;
}
class CourseCmd {
CourseDomain course
}
class CourseDomain {
Long id
}
```

was hoping that it will bind to

> StudentEnrollmentCmd -> student -> id (this works)
> StudentEnrollmentCmd -> courses -> course -> id (this doesn't work)

which seems to work in grails 2.2.4 but fails in 3.3.7 with the following exception

> No such property: course.id for class: student.CourseCmd

Here is the test case which illustrates the problem

```
void 'databinding from request parameters'() {
given:
// request with simple formdata: student.id=1&courses[10].course.id=10
MockHttpServletRequest request = buildMockRequestWithParams('POST',['student.id':'1','courses[10].course.id':'10']);
DataBindingSource source = bindingSourceCreator.createDataBindingSource(null,null,request);

// databinder & command object
def binder = new SimpleDataBinder()
def obj = new StudentEnrollmentCmd()

when:
binder.bind(obj,source)

then:
// this should not throw an exception, but throws an exception
MissingPropertyException ex = thrown()
System.out.println ( "Exception thrown:" + ex.message );

// student.id is bound correctly
obj.student.id == 1
// the following doesn't work
obj.courses['10'].course.id == 10
}
```

Here is the link to full spec... https://github.com/swzaidi/sample/blob/master/grails3.3.7/src/test/groovy/student/DataBindingSpec.groovy

Looking for some help on how to pass the form data so that it binds to above command objects properly.

### Environment Information

- **Operating System**: MAC
- **Grails Version:** 3.3.7
- **JDK Version:** 1.8

### Example Spec

- https://github.com/swzaidi/sample/blob/master/grails3.3.7/src/test/groovy/student/DataBindingSpec.groovy

Note: we illustrated the same problem in #11245, which wrongly started of as a LazyMap binding issue, that issue can be closed.

Contributor guide

Open the contributing guide

Research direction

Start with the reproduction in DataBindingSpec.groovy and trace SimpleDataBinder.bind against the posted student.id and courses[10].course.id parameters. Compare the behavior with the stated Grails 2.2.4 and 3.3.7 versions, using the reported MissingPropertyException as the failure point. Done means the supplied test binds both nested ids without throwing.

Written by the indexing model from the issue text.

Assessment

Tech stack
groovy
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.