Custom Grails Constraint doesn't seem to work - grails

I have been trying to create a custom constraint in a Grails Project (see constraint code below).
import org.codehaus.groovy.grails.validation.AbstractConstraint
import org.springframework.validation.Errors
class BuscaConstraint extends AbstractConstraint {
public static final String CONSTRAINT_NAME = "busca"
protected void processValidate(Object target, Object propertyValue, Errors errors) {
}
boolean supports(Class type) {
return type && String.class.isAssignableFrom(type);
}
String getName() {
return CONSTRAINT_NAME;
}
}
As you can see, this constraint doesn't actually validates anything. Instead, it's just a flag to customize the property's rendering in the scaffolding generation.
After creating the class above, I added the following line in the file Config.groovy:
ConstrainedProperty.registerNewConstraint(BuscaConstraint.CONSTRAINT_NAME, BuscaConstraint.class)
..and added this constraint to a class's property:
class ThatClass {
def someProperty
static constraints = { someProperty (unique:true, busca: "nome")
}
However, if I try to get the result of the expression
ThatClass.constraints.someVariable.getAppliedConstraint("busca"),
all I get is null.
I based my approach in some blog posts such as this one and from a constraint in Grails' github repo(however I can't see how they are configured there).
What am I doing wrong?
Has the configuration of Grails' custom constraints changed recently?

It looks your constraint is good. I use something very similar in my Url Without Scheme Validator Plugin, in class UrlWithoutSchemeConstraint and it works like a charm in recent Grails (2.3.x, 2.4.x).
However, I never tried to access it at runtime, so I'd try to investigate this area. For example, have you tried ThatClass.constraints.someProperty.busca?

I am also using my constraint as a tag in a Grails 2.4.4 project. The constraint can be accessed with the following code:
domainClass.constraints[p.name].getMetaConstraintValue("encodeAsRaw")
Where p.name is the property name and "encodeAsRaw" is the name of my constraint. I am using this code successfully in a couple of .gsp files.
If just using as a tag, you don't even need to create a custom constraint class and register it. It's enough just to check for its existence with the getMetaConstraintValue method.
For completeness, here is my constraint definition in my domain class:
myProperty(nullable:true, blank:true, unique:false, maxSize:1000, encodeAsRaw:true)

Related

Is any package name restrictions applied in grails?

I have created a Domain class called Action under package promotion
package promotion
class Action {
String name
String code
String address
static constraints = {
name blank:false
code maxSize:5
address nullable:false
}
}
Issue: Here my problem is I can not generate controller&views. And also I can not change default error messages from message property for my constraints
example: promotion.Action.name.nullable=Please enter the action name
Note: But if I change my package name "promotion" to something like "com.app.act" it works fine.
Try to make package name little brief. So it can be a good coding practice also

Grails Scaffolding

I am recently working on grails and would like to know how to do more complex scaffolding
For example, if I want to Scaffold a class
class Book{
Author a
Publisher p
// ....
}
Author class
class Author{
String firstName
String lastName
// ...
}
Publisher class
class Publisher{
String name
String address
// ....
}
Now if I have a BookController
class BookController{
static scaffold = true;
}
I have a layout of
Author Publisher
However if I want a layout with
AuthorID AuthorFirstName AuthorLastName PublisherName PublisherAddress
I have looked through the http://grails.org/doc/latest/guide/scaffolding.html, however, I am unable to set it to the given property. I would like to know I am able to accomplish it? A tutorial would be helpful.
The scaffolding plugin within Grails is not designed to handle these types of complex views out of the box. You have a few options:
Use the install-templates command and modify the scaffolding templates to handle your needs.
Re-design your domain class to use embedded Author and Publisher. This will change the scaffolding output, but it also will change a lot more too. I wouldn't use this option unless you understand all the changes this will make to your domain model.
Generate the code using scaffolding then customize the output to suit your needs.
Of the three options presented here I would recommend the third as it makes the most sense to address the narrow scope of your issue.
You could also use transients. But transients aren't displayed by default.
You need to modify the templates and explicitly hide otherwise hidden fields using constraints i.e. id
NOTE: code below untested, for illustration purposes only.
//optional, but allows code completion in IDE ;-P
String authorName
String getAuthorName(){
return a.firstName + ' ' + a.lastName
}
static transients = [authorName:String]
static constraints = {
id(display:false)
}

Property [] of class [] can not be null error in Grails

I am new to Grails and getting this error on two out of my three domains when I run the project on all the domains content. The domain the works is
class Location {
def scaffold = true
String company
String name
String address
static belongsTo=[company:Company]
static constraints = {
}
}
The domain that does not work is
class Report {
def scaffold = true
String title
String location
Date published
static belongsTo=[location:Location]
static constraints = {
}
}
I can not see the structural or syntax issue that is trowing the errors. I have been trying a variety of adds and subtracts and can not seem to find anything that address this error at a basic level. Again I have just started using Grails and Groovy
After doing the changes told by #araxn1d, you should also check the constraints. By default all properties are not nullable (that's why you're getting for example the error for the title property)
If you already have data in your database you have two options:
Update your database and set the correct values in each table or row
Set each property in the domain as nullable. For example
static constraints = {
title nullable:true
}
Are you creating a Report with no properties set? By default, Grails will check that all properties are not null. If you want to allow the user to leave a certain field undefined (null), then you have to explicitly tell Grails in the constraints map:
static constraints = {
propertyName nullable: true
}
Seems like error is in this line:
String location
location is String type, but should be Locationtype. The same as String company in Location domain should be Company company.
I think the problem is that you've changed the structure of the domain class after you generated the automatically created views/controller for the domain.
I fixed it by just deleting the offending domain along with the controller/views file and recreating them. I'm sure you could root through and find the offending code though.

constraints in grails

Hi I am having some trouble getting my constraints to work in my grails project. I am trying to just make sure that the field for Site_ID is not left blank but it still accepts an blank input. Also I am trying to set the order in which the fields appear but even that is not reflecting on the page when I try it out. Here is the code:
package translation
class J2_Translations {
String Site_ID
String I18NKey
static constraints = {
Site_ID(blank:false)
I18NKey()
}
}
and here is my code for the controller, I am not doing anything special I just want the constraints to work
package translation
class J2_TranslationsController {
def scaffold = J2_Translations
}
thanks,
Ameya
Grails is a convention-over-configuration framework. Make sure you follow the standard Java naming conventions. Properties should be named with camel-case identifiers with the leading character in lowercase. For example:
String siteId
String i18nKey

How do define default display order with derived domain classes in Grails?

In Grails 1.2.1, I use a base domain class and derived domain classes and define constraints in all of them. The scaffolding templates (I use the i18n ones) determine the default field display order based on these constraints. My problem: No matter what I do, the fields from the base class are always displayed before the fields from the derived classes.
So here's an example of such classes:
abstract class BaseEntity {
String name
String description
String link
static constraints = {
name(blank: false)
description(blank: true, maxSize: 131072)
link(url: true, blank: true)
}
}
class BacklogItem extends BaseEntity {
String type
String priority
static constraints = {
name(unique: true)
type(inList:["Bug", "Enhancement", "New Feature", "Task"])
priority(inList:["Low", "Medium", "High"])
description()
link()
}
}
Now I'd like the fields to show up in the order as defined in the Item constraints (description and link at the end). But no matter what I do, name, description and link are always the first three fields in create/show/edit, due to the base class, even when I try to force them to the end in the derived class constraints.
How would you solve this?
I will move the constraints away from the base class and duplicate them in each derived class. This means code duplication, but it allows me to specify the display order in each (derived) class the built-in Grails way.

Resources