Quantcast

How To Put A Constraint On Relationships In A Domain Class?

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

How To Put A Constraint On Relationships In A Domain Class?

antoaravinth
Hi all,

I have a domain three domain class like this :


Tasks.groovy

class Tasks {
    static belongsTo = [ user : User ]
        //other fields
    Date startDate
    Date endDate
}
User.groovy

class User {
    //relationships. . . .
    static belongsTo = [ company : Company, role : Role, resource : Resource]
    static hasMany = [ holidays : Holiday, tasks : Tasks]
    //other fields
    }
Holiday.groovy

class Holiday {
    static belongsTo = User
    Date startDate
    Date endDate
    //other fields
}
Now when I create a Tasks instance, I want to put a constraint such that the Tasks startDate and endDate doesn't fall within the User's Holidays startDate and endDate. And throw and error if it has.

I want a way to put this constraint on my domain class itself(i.e on Tasks).

Is it possible to do so?

Thanks in advance.
Ant's
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How To Put A Constraint On Relationships In A Domain Class?

Graeme Rocher-2
With a customer validator, see the docs for details

-- 
Graeme Rocher

On Friday, February 24, 2012 at 6:58 AM, antoaravinth wrote:

Hi all,

I have a domain three domain class like this :


Tasks.groovy

class Tasks {
static belongsTo = [ user : User ]
//other fields
Date startDate
Date endDate
}
User.groovy

class User {
//relationships. . . .
static belongsTo = [ company : Company, role : Role, resource :
Resource]
static hasMany = [ holidays : Holiday, tasks : Tasks]
//other fields
}
Holiday.groovy

class Holiday {
static belongsTo = User
Date startDate
Date endDate
//other fields
}
Now when I create a Tasks instance, I want to put a constraint such that the
Tasks startDate and endDate doesn't fall within the User's Holidays
startDate and endDate. And throw and error if it has.

I want a way to put this constraint on my domain class itself(i.e on Tasks).

Is it possible to do so?

Thanks in advance.

-----
Ant's
--
Sent from the Grails - user mailing list archive at Nabble.com.

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


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

Re: How To Put A Constraint On Relationships In A Domain Class?

antoaravinth
Well the custom validator is working for putting a constraint on the same Domain class instance. Not on the case of relationships.
Ant's
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How To Put A Constraint On Relationships In A Domain Class?

Graeme Rocher-2
You can look at the relationships of a domain class from the domain class. Just be careful because of the association is not initialized and lazy you can run into trouble. For this kind of thing you really need to load a separate instance to avoid interfering with the flushing process.

-- 
Graeme Rocher

On Friday, February 24, 2012 at 10:27 AM, antoaravinth wrote:

Well the custom validator is working for putting a constraint on the same
Domain class instance. Not on the case of relationships.

-----
Ant's
--
Sent from the Grails - user mailing list archive at Nabble.com.

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


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

Re: How To Put A Constraint On Relationships In A Domain Class?

Matti van Aert
Is this what you're looking for.

    static constraints = {
        startDate(validator: {val, obj -> return obj.user?.holidays?.every { !(it.startDate.after(val) && it.endDate.before(val))}})
        endDate(validator: {val, obj -> return obj.user?.holidays?.every { !(it.startDate.after(val) && it.endDate.before(val))}})
    }


Kind regards,
Matti van Aert


2012/2/24 Graeme Rocher <[hidden email]>
You can look at the relationships of a domain class from the domain class. Just be careful because of the association is not initialized and lazy you can run into trouble. For this kind of thing you really need to load a separate instance to avoid interfering with the flushing process.

-- 
Graeme Rocher

On Friday, February 24, 2012 at 10:27 AM, antoaravinth wrote:

Well the custom validator is working for putting a constraint on the same
Domain class instance. Not on the case of relationships.

-----
Ant's
--
Sent from the Grails - user mailing list archive at Nabble.com.

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





--
Met vriendelijke groet,
 
Matti van Aert

Achter de Molen 45
4873 GW Etten-Leur
M: +31 (0)6 5499 4867

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

Re: How To Put A Constraint On Relationships In A Domain Class?

antoaravinth
In reply to this post by Graeme Rocher-2
Thanks Graeme Rocher will look into it.

On Fri, Feb 24, 2012 at 3:55 PM, Graeme Rocher-2 [via Grails] <[hidden email]> wrote:
You can look at the relationships of a domain class from the domain class. Just be careful because of the association is not initialized and lazy you can run into trouble. For this kind of thing you really need to load a separate instance to avoid interfering with the flushing process.

-- 
Graeme Rocher

On Friday, February 24, 2012 at 10:27 AM, antoaravinth wrote:

Well the custom validator is working for putting a constraint on the same
Domain class instance. Not on the case of relationships.

-----
Ant's
--
Sent from the Grails - user mailing list archive at Nabble.com.

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





If you reply to this email, your message will be added to the discussion below:
http://grails.1312388.n4.nabble.com/How-To-Put-A-Constraint-On-Relationships-In-A-Domain-Class-tp4416287p4416747.html
To unsubscribe from How To Put A Constraint On Relationships In A Domain Class?, click here.
NAML

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

Re: How To Put A Constraint On Relationships In A Domain Class?

antoaravinth
In reply to this post by Matti van Aert
The solution given by Matti van Aert, is not working. I did the same as what you have said, but that doesn't work.
Ant's
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How To Put A Constraint On Relationships In A Domain Class?

talldave

ants -

think i have a solution for you, although i'd be curious to hear more from graeme about how this might change if any of the associations were lazy.  perhaps i need to revisit the GORM gotcha series, if it's covered there.  if not, maybe time for part 4?  :)


i didn't try matti's solution, but as a general style note i'm not personally a fan of navigation on an object's relationships outside of that object, if possible.  i think that leads to making code more difficult to refactor, so i try and provide convenience methods that state the intent of the relationship navigation.  so in the code below i put a "isUserAvailable()" method on the User domain, and had the Tasks custom validator call that method.

hope this makes sense, and let me know if it works for you - or doesn't.  from just a little testing in the grails console i think it does what it should.

fun little exercise.  :)

dave


btw, i set holidays to a SortedSet on the User class, and in a real-world scenario i'd probably think about using that with a for loop instead of the ".any" in the isUserAvailable() method.  i'd trace the sql queries and see how many it executes.  but basically with a SortedSet according to holiday start dates, if your task date is in January there's no reason to keep checking the holiday dates for the rest of the year.  does that make sense?  and the reason for a for loop instead of a closure in that scenario, is that as far as i know you can't break out of a closure.



class Tasks {

        static belongsTo = [user:User]

        Date startDate
        Date endDate

    static constraints = {
    startDate( nullable:false,
    validator: { val, obj ->
                                obj?.user?.isUserAvailable( val, obj?.endDate )    
    })
    endDate( nullable:false )
    }
    // wants constraint so that Task cannot be created if task start/end date falls within any of the User's Holiday's start/end date

}



class User {

        SortedSet holidays

        static hasMany = [
                holidays: Holiday,
                tasks: Tasks
        ]

    static constraints = {
    }

    static transients = ['isUserAvailable']

    def isUserAvailable( startDate, endDate ) {
    def datesConflictWithHolidays = this.holidays?.any {
    startDate.after( it.startDate ) && startDate.before( it.endDate )  \
    || endDate.after( it.startDate ) && endDate.before( it.endDate )  
                }

    return ! datesConflictWithHolidays
    }

}



class Holiday implements Comparable {

        static belongsTo = User

        Date startDate
        Date endDate

    static constraints = {
    startDate( nullable:false )
    endDate( nullable:false,
    validator: { val, obj ->
    val?.after(obj?.startDate)
    })
    }

    def compareTo(that) {
    this?.startDate <=> that?.startDate
    }

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

Re: How To Put A Constraint On Relationships In A Domain Class?

antoaravinth
Thanks for the reply and some good tips. Now consider the scenario where I'm selecting the users from a drop down box and I want to check that particular users holiday stats. This is very much easy if I put the code in my controller and check them. But is there a way to the same in domain class via a validator constraint?
Ant's
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How To Put A Constraint On Relationships In A Domain Class?

talldave
i'm not sure i'm following the question.  are you trying to see the user's holidays before saving the Tasks domain?  if so, doing something like the isUserAvailable() method could be reused beyond just the validator, and called via ajax to provide immediate feedback to the UI as to whether the dates entered are valid or not, prior to trying to actually persist the data to the DB.  remember that the validator constraints will be checked only if domain.validate() or domain.save() is called.  (or something similar, maybe .merge() or whatever else.)

again, generally speaking, i try to keep my controllers as simple as possible and have them focusing on handling navigation primarily.  i shoot for putting any/most real logic in the domain or service layers.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: How To Put A Constraint On Relationships In A Domain Class?

antoaravinth
Thanks mate, I got into working, Thanks for your advice too... :) 

On Mon, Feb 27, 2012 at 9:06 AM, talldave [via Grails] <[hidden email]> wrote:
i'm not sure i'm following the question.  are you trying to see the user's holidays before saving the Tasks domain?  if so, doing something like the isUserAvailable() method could be reused beyond just the validator, and called via ajax to provide immediate feedback to the UI as to whether the dates entered are valid or not, prior to trying to actually persist the data to the DB.  remember that the validator constraints will be checked only if domain.validate() or domain.save() is called.  (or something similar, maybe .merge() or whatever else.)

again, generally speaking, i try to keep my controllers as simple as possible and have them focusing on handling navigation primarily.  i shoot for putting any/most real logic in the domain or service layers.


If you reply to this email, your message will be added to the discussion below:
http://grails.1312388.n4.nabble.com/How-To-Put-A-Constraint-On-Relationships-In-A-Domain-Class-tp4416287p4423534.html
To unsubscribe from How To Put A Constraint On Relationships In A Domain Class?, click here.
NAML

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

Re: How To Put A Constraint On Relationships In A Domain Class?

talldave
cool, happy to help!
Loading...