Saturday, January 5, 2008

Survey Project--A Grails Implementation

I started small grails application today to enable creating surveys and questions and tracking questions and results. The domain classes are:
  • Survey: the primary table that defines a survey project
  • SurveyQuestion: object to hold a specific question mapped to a survey
  • SurveyResponder: the person that is answering the survey questions
  • SurveyResponse: the recorded answers that the reponder enters
And here is the proposed ER diagram, created using dbDesigner.

As the diagram shows, surveys have many questions, questions have many responses. Surveys also have many responders and responders have many responses. You can also see that this is a very simple survey with no branches.

Grails/GORM Implementation:
I began by generating the Survey and Survey question domain classes and basic validation tests. Next was to create the SurveyReponder and SurveyResponse classes. The implementation was straight forward, but I had to fiddle with the domain class definitions to get hibernate to understand my intent. Just a matter of specifically defining class references in dependent models rather than depending on the 'belongs_to' and 'has_many' declarations.

Datasets and Loaders (Fixtures):
Unlike Rails, Grails doesn't use fixtures for test data. Lucky for me I have a Grails enhancement the solves this based on a sandbox proposal from the Grails guys. So I generated the dataset loader classes using: grails create-dataset [domain]. This creates the following:
  • a DataLoaderBootStrap class in grails-app/conf/ (unless it exists)
  • a DomainDataset class in src/groovy/datasets
  • a set of random data to be loaded
An example of what gets created is here:

> grails create-dataset survey
> ...
> file grails-app/conf/DataLoaderBootStrap.groovy exists...
> created file src/groovy/datasets/SurveyDataset.groovy

The SurveyDataset class looks like this:

class SurveyDataset {
dataset = {
def set = [
[ name:'879',description:'510',email:'680' ],

return set

load() {
dataset().each { data ->
obj = new Survey( data )

As you can see, the data is contrived but all of the fields are present and other than the actual data, the script is good to go. I'll show how this data can be loaded from the console, command line and within test scripts in a later post.


Marcos Silva Pereira said...

Hi, could you please talk more about your create-dataset task? Do you implement that?

Kind Regards

darryl.west said...

Hi Marcos,

I have a rough implementation now that's not ready for prime-time. I plan to put it into open source as soon as I work out the bugs.

A short list of features includes:
1) independent loaders for development, test and production placed in a DatasetBootStrap class
2) ability to load data during test (or any time) to refresh tables
3) ability to run the loaders from the command line (grails task)
4) code generation for Dataset classes.

Thanks for the interest.

-- darryl

Michael said...

nice project. do you have any source code availible jet?

darryl west said...

Sadly, this project ran out of funds shortly after it started. We did get funding for a follow on project to create an interface to UPS shipping that is currently open source.

translucent_eye said...

Would you mind pointing me to the opensource version of your tracking software for UPS that you mentioned?

I am actually working on a survey package in Groovy/Grails, but I'd be interested in seeing that one as well.