Modifying Grails constraints during runtime - grails

The problem:
In my web application I defined some constraints. That I can save the domain class to "drafts" also when the constraint properties are not matching I set the constraint nullable to true. In the following process I can modify the object and after that to finalize the process I want to make a full validation. That means I want to add the nullable:false property.
Question 1: Is there a way to extend/ change constraints during the runtime?
Question 2: Is there a way to iterate through all constraints also when a domain class has nested constraints (e.g. other domain class references)
Thanks

Answer 1: Yes you probably can.
Answer 2: Yes.
So example:
def user = new User()
for(constraint in user.constraints) {
constraint.value.setBlank(true)
constraint.value.setNullable(false)
}
For nested fields:
for(constraint in user.someNestedFields.constraints) {
....
}
But i would not recommend to do so. It looks like bad architecture.
To save your domain entity without validation just call save(false).

Related

Grails dynamic "inList"

This is almost identical to this old question: Dynamic define the inList constraint using database query which was essentially unaddressed, perhaps there have been advances in the years since that was asked.
I'd like to populate the inList parameter of a domain attribute with values from another domain. Due to auto-generated views (scaffolding, filterpane), this needs to come from inList rather than a custom validator.
class MyDomain {
String someValue
static constraints = {
someValue(nullable: true, maxSize: 50, inList: SomeOtherDomain.list()*.name)
}
}
This gives the following error on startup:
Caused by: java.lang.IllegalStateException: Either class [thepackage.SomeOtherDomain] is not a domain class or GORM has not been initialized correctly or has already been shutdown. Ensure GORM is loaded and configured correctly before calling any methods on a GORM entity.
I know, the "correct" way to handle this is to make someValue an instance of SomeOtherDomain instead of just storing the name, but that doesn't quite fit. We want to be able to delete an instance of SomeOtherDomain without breaking the saved value of the owning domain... the domain with the deleted value will be invalid going forward, and would have to be updated before saving, but archived/locked records will still exist and can be displayed.
You can specify value lists for filterpane like this:
<filterpane:filterPane domain="MyObject" filterPropertyValues="${['someValue':[values: SomeOtherDomain.list().collect{it.name}]]}" />
And then just use a custom validator to actually validate. I'm not sure what scaffolding might use the inList but easy enough to get around that if you're OK with replacing a few scaffolded pages with static ones.

Can grails domain class include custom criteria in every query?

I'm creating a domain class that will connect to an existing database. Unfortunately multiple domain objects are stored in the same table (the table is very generic), and I'm trying to find a way to include additional criteria in each query that is made through GORM.
For example, I have an Article domain class which exists in the exp_channel_data table. The table has site_id and channel_id columns, which will be used to indicate if the row is actually an Article (where site_id=2, and channel_id=3).
I can setup custom constraints to make sure that validation works properly:
static constraints = {
site_id validator: { it == 2}
channel_id validator: { it == 3}
}
But I want to prevent invalid Articles from even being returned in the first place (keeping things clean, and also for performance reasons).
What I'm envisioning is the ability to override every query that goes out from my domain class, and insert where site_id=2 and channel_id=3 so that I don't even see invalid rows.
Any thoughts would be appreciated, thanks in advance.
UPDATE
After using the hibernate-filter plugin (suggested below), this is what I'm using in the domain class to prevent unnecessary entries from being returned.
static hibernateFilters = {
site_idFilter condition: 'site_id=2', default: true
channel_idFilter condition: 'channel_id=3', default: true
}
From what you are describing here, since it's per domain class, this looks to be a perfect situation for using the Hibernate filters plugin for Grails. This way you can define default constraints to be applied to criteria from those domains. Well worth a look to see if it will meet your needs.

Default Constraints in Entity Framework

Very simple question that NO ONE has directly answered. Is there no way to insert an entity using EF4 that uses the database default constraint and yet allows that field to be updated later? There doesn't seem to be. When I have a date property for instance and want it to use the database default, I seem to have two options:
1) Set the "StoreGeneratedPattern" to "Computed" or "Identity" which prevents me from updating it later.
2) Ignore the database default entirely and set the default value myself.
Neither one of these options will work for me, and this seems to be a huge weakness with the framework. Any ideas? Is this bug resolved in EF5.
No.
Relevant UserVoice suggestion.
You could extend the generated class and set the default values in the constructor of the patial class.
public partial MyEntityClass MyEntity
{
public MyEntityClass()
{
this.DefaultValueProperty = defaultValue;
}
}

How can I use more than one set of constraints on a single domain class in Grails?

I need to choose a set of validation rules at save time. Ideally I would like to be able to define more than one set of constraints in the domain class:
class Account {
...
static constraints = { ... }
static constraints2 = { ... }
}
I know I can do my own validation in code (account.errors.rejectValue(...) etc) but I am looking to save some time by using the built in Grails validation if possible.
This is what Command Objects are for.
The reason you can't just swap out validation is that the validation also helps define the database structure, like setting a field to be non-null, or non-blank, or having a specific length. Turning off "non-null", for example, could break the database structure.
Command objects, on the other hand, are designed to have their own unique set of validation rules. It's not the cleanest method (now you are tracking the same structure in more than one situation), but it's better in a lot of ways.
It allows you to securely accept input parameters without worrying that something that shouldn't be processed gets set.
It creates cleaner controllers, since the validation logic can all be handled within the Command Object, and not sprinkled through the controller method.
They allow you to validate properties that don't actually exist on the object (such as password verification fields).
If you think you really need multiple sets of constraints, you are most likely either a) over-complicating the domain object to represent more information than it really should (maybe break it up into several one-to-one related objects), or b) incorrectly setting the constraints in the first place.†
In my experience, usually it's a that happens when you feel the need to swap out constraints.
† That being said, it can (rarely) make sense. But Command objects are the best solution in this situation.
you can use the validator constraint, see: http://www.grails.org/doc/latest/ref/Constraints/validator.html
within one validator constraint you can perform more checks than one and return diffrent error codes, e.g.
static constaints = {
name: validator { value, obj ->
if (value.size() > 10)
return [invalid.length]
else if (value.contains("test"))
return [invalid.content]
return true
}
in message.properties
domainClass.propName.invalid.content = ...
}

Grails: derived fields in domain classes

Suppose I have a domain class branch which has several members:
…
static hasMany = [ members:Member ];
…
Now suppose I want to have the number of members of that branch readily available, to have it displayed in the list and view actions, so perhaps storing that information into a variable in the domain class itself would be a good idea?
…
Integer memberCount = members.size();
static constraints = {
memberCount(editable:false);
}
…
(Is this the correct syntax?) Edit: This is not the correct syntax. I cannot assess the size of the members list, as it doesn’t exist yet and grails will complain about size() not being applicable to null objects. What else could I try?
However, as memberCount is now a variable in the domain class, it is possible to assign a value to it upon creation of the Branch (which is contra-intuitive) and it will not be updated automatically once a new Member is added.
It is of course possible to reach the desired result in a different way. I could manipulate the view.gsp and list.gsp in the /Branch directory, add some additional <td>s there etc. But that does not seem very elegant to me.
Basically, I think what I am looking for is some way to tell grails that a certain variable is derived, should not be setable by the user, but update whenever necessary. Is there such way?
You can add any property you don't want persisted to the transients static list:
static transients = ['memberCount']
See this page in the manual
Also, this StackOverflow question answers the same question
Also, a better way to do derived properties may be to use the Derived Properties feature of GORM

Resources