Quantcast

1.3.7 using command object to extend a domain class

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

1.3.7 using command object to extend a domain class

wuestenfuchs2
CONTENTS DELETED
The author has deleted this message.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: 1.3.7 using command object to extend a domain class

burtbeckwith
You can put the common fields and the mapping and constraints blocks in a base class in src/groovy, then extend that in both the domain class and command object. Since it's regular Java/Groovy inheritance there's no Hibernate subclassing behavior.

Burt

>
> Hello,
> i want to use a command object that extends an existing domain class,. For example my user domain doesn't have a "passwordAgain" field, but I don't want to rewirte my entire domain class again as a command object and I think this would be a elegant way to do the job. Extending the domain class will break the code. Does someone know how to fix it or is my approach wrong?
> Thank you for any responses, Bye    

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: 1.3.7 using command object to extend a domain class

wuestenfuchs2
CONTENTS DELETED
The author has deleted this message.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: 1.3.7 using command object to extend a domain class

Dean Del Ponte-2
I'm running into the same error described by Christian.  Does anyone know of a workaround?

Thanks!

Dean Del Ponte

On Thu, Jul 7, 2011 at 5:58 AM, Christian Wüstenfuchs <[hidden email]> wrote:
Hello, 

thank you or the quick response Burt. This approach works great, I tested it and will definitely use it a lot. I fond your fixed bug for this with abstract classes: http://jira.grails.org/browse/GRAILS-6405

In my concrete application the domain class is used for spring-security-core and somehow this will break it again. "An association from the table user_role refers to unmapped class <User class>" Spring security breaks the code. Strange, also the other way round: user domain class doesn't extends a file, file in src/groovy extends user domain class and the command objects extends the src/groovy file will also break.

Do you know also a trick here? 

Thank you, Bye
Chris




> From: [hidden email]
> To: [hidden email]
> Date: Wed, 6 Jul 2011 21:19:38 -0400
> Subject: Re: [grails-user] 1.3.7 using command object to extend a domain class

>
> You can put the common fields and the mapping and constraints blocks in a base class in src/groovy, then extend that in both the domain class and command object. Since it's regular Java/Groovy inheritance there's no Hibernate subclassing behavior.
>
> Burt
>
> >
> > Hello,
> > i want to use a command object that extends an existing domain class,. For example my user domain doesn't have a "passwordAgain" field, but I don't want to rewirte my entire domain class again as a command object and I think this would be a elegant way to do the job. Extending the domain class will break the code. Does someone know how to fix it or is my approach wrong?
> > Thank you for any responses, Bye
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
> http://xircles.codehaus.org/manage_email
>
>

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: 1.3.7 using command object to extend a domain class

virtualeyes
In reply to this post by wuestenfuchs2
If command objects supported inheritance and shared constraints in src/groovy, I would have no problem duplicating domain fields and naming the shared constraints (in other words, duplicate the fields, but DRY the validation logic)

What I do not enjoy is repeating constraints as below in Config.groovy, LoginCommand, ResetPasswordCommand, SignupCommand, etc.

email      size:7..100, email:true, blank:false
password      blank:false, password:true, validator: { val->
        return (
                ( val =~/(?=.{8,})(?=.*[a-z])(?=.*[A-Z])(?=.*[\d])(?=.*[\W])/ ) )?
                true:
                'not.strong.password'
        )
}

Furthermore, ignoring inheritance (i.e. sticking command directly in Controller), specifying a shared constraint that has domain-specific rules (nullable:true, unique:true), breaks with baffling validation MME on line number -1 of unknown class, fun.

I JIRA'd earlier today:
http://jira.grails.org/browse/GRAILS-8074

@Validateable is no help either, no shared constraint support yet.  Extending domain as folks in this thread are doing would work if compile-time @Mixin actually worked so we could do multi-inheritance.  Single inheritance is too limited, imo, to solve this problem.

For example, I have a src/groovy an abstract Person class which several domains extend:
abstract class Person {

        String firstName
        String lastName
        String email
        String phone

        static constraints = {
                firstName shared:"firstName"
                lastName shared:"lastName"
                email shared:"email", nullable:false, unique:true
                phone size:0..30
        }
}

How would I extend Person to create a LoginCommand object? LoginController just has email & password fields; furthermore, unique constraint mapping on email will break the command (as there is no domain instance to reference).  In the end you wind up with some hacked workaround.  @Mixin would be great, or some kind DRY command object support where you could both extend and draw on shared constraints in Config.groovy.

Guess for now just repeat validation logic everywhere and move on....
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: 1.3.7 using command object to extend a domain class

virtualeyes
In reply to this post by Dean Del Ponte-2
Yes, do not use Command objects & do not use @Validateable.

Instead, create a domain subpackage and create your "Command" objects there like so:
package com.foo.command

// I support inheritance too, desert DRY validation
class Login {

        static mapWith = "none" // don't map table to DB
       
        String email
        String password
        static  constraints = {
                email shared:'email' // look, shared constraints (good luck with Command and @Validateable)
                password shared:'password'
        }
}

then in your controllers import the Command (aka transient domain) and
def auth() {
        Login cmd = validate(Login) // see base controller validate method below (could service it as well if you like)
        if(cmd.hasErrors()) {
                println cmd.errors // IDE "knows" hasErrors(), errors, etc. so no underlines
        }
}

// in base controller
Object validate(Class dc) {
        def o = dc.newInstance(params)
        o.validate()
        o
}

Giant pile of suck that was wasting an entire day trying to get Command and @Validateable working with shared constraints and inheritance.  Current implementation is sopping WET if, like me, you have validation needs that share constraints across at least 5 different controllers.

Apologies for the rant, but the back & forth between rapid development and utterly wasted days is making my deadline more & more unrealistic.
Loading...