Grails domain class: unique constraint for multiple columns - grails

Suppose a simple Grails domain class:
class Account {
String countryId;
String userName;
String password;
static constraints = {
...???...
}
}
It is required that user names are unique for a particular countryId, thus there must be a unique contraint on two columns. How to express this in the constraints definition?

userName(unique: ['countryId'])
You can include as many other properties in the array that make up the other properties that must be considered in the "unique" constraint on the username.
So, for example if you wanted to make userName unique within a countryId and provinceId it would look like this:
userName(unique: ['countryId', 'provinceId']

Related

grails: primary key from view

I have a requirement to create Employee and Role domain with ids which should be inserted at the time of creation and not manually inserted via code.
Following is attached code for Role.groovy
package pocgrails1
class Role{
String roleId
String roleName
static hasMany = [RoleACL]
static mapping = {id generator: 'assigned',name:"roleId",type:'string'}
static constraints = {
roleName blank:false
roleId blank:false
}
String toString(){
return id
}
}
I am having issues while generating the primary key from the view.
By default the scaffold does not generates the field to insert the primary key value.
I already have looked into several blogs and posts but none were of much help.
What should be the correct approach for this.
Many thanks in advance.
Rohit
Hard to understand what do you want to do. If you want to change primary id key define it as String id and change mapping:
class Role{
String id
static mapping = {
id column: 'role_id', generator: 'assigned'
}
}
When you save object an id will be generated for you and persisted to database, no need to create anything manually

Grails domain ID column validation issue

I have a simple domain object
class MyDomain
{
String id
String name
static constraints =
{
id unique:true
name nullable:true
}
static mapping =
{
table 'schema.MyDomain'
id column:'MY_ID', type:'string', generator:'assigned'
}
}
The issue I am having is when I call validate on the object, it returns true even when the id field is null. I had thought that all columns were nullable:false unless explicitly stated otherwise. If I change the line
id unique:true
to
id unique:true, nullable:false
then it seems to work fine. My main question is, why do I have to explicitly set nullable for the ID column? It is just a small line of code, but I don't like just adding in the tag of code without understanding why in case it is a symptom of a bigger problem.
The id column is auto generated and auto populated(when versioning is turned on[true by default]) and you shouldn't have to declare a new one.
This default id column is nullable:false by default and you can still set the mapping properties and id generation strategies like you have done above against it.
However if you want to define the default constraints for all domain in you app, you can do it globally by setting thwe following in your config.groovy file.
grails.gorm.default.constraints = {
myShared(nullable:true, size:1..20)
}
For more on constraints see the Grails documentation.

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.

How can fields in Grails represented by a combobox be made optional?

I'm doing my first experiments with Grails and am looking for a way to have fields represented by a combobox (such as one-to-one domain associations and numbers with a narrow range constraint) to be optional, i.e. there should be an empty entry in the combobox.
How can this be achieved? I've tried both adding a nullable:true constraint and listing the fields in the optionals static property, but neither produces the desired result.
These are my domain classes:
class Customer {
String name
}
class Book {
static optionals = ['year','loanedTo','loanedSince']
static constraints = {
title(blank:false)
author(blank:false)
year(range:1900..new Date().getAt(Calendar.YEAR), nullable:true)
loanedTo(nullable:true)
loanedSince(min:new Date())
}
String title;
String author;
Integer year;
Customer loanedTo;
Date loanedSince;
}
I've found that the nullable:true constraint actually does have the desired effect - however, it does not take effect immediately; you have to restart Grails to see it.
If you've generated your scaffolding code, you'll also have to regenerate it so that the option is present.
I don't think optionals is still supported: http://jira.codehaus.org/browse/GRAILS-472
The tag also has an attribute for a default, "not selected" value: noSelection. You can use it like this to have the drop-down default to "---" instead of your regular values:
noSelection="${['':'---']}"
In the controller, the default value shows up as an empty string, as specified in the first part of the value.

Composite foreign key columns in GORM

I need to customize the column names for composite foreign keys in GORM, and I didn't find any document that shows how to do it. I know how to customize PK columns, and how to customize a single-column FK, but not multi-column FK. Is it possible at all?
Thanks.
A domain class with composite id must implement the Serializable interface.
class Person implements Serializable {
...
}
You need the "id: composite" construct in your object mapping closure.
I have to leave for work, so here it is in brief:
class Person {
String firstName
String lastName
static mapping = {
id composite:['firstName', 'lastName']
}
}
Grails: Object Relational Mapping

Resources