Command Object and hasmany - grails

I'm trying to use the commandObject to validade my data when I submit my form. Can I validate a hasMany relation in commandObject. My cenario is something like this.
Tow simple classes whith hasMany relationship:
class Book{
String nameBook
}
class Author{
String nameAuthor
static hasMany = [books:Book]
}
Simple commandObject with hasMany that i want to validate when submit form.
#grails.validation.Validateable
class MyValidateCommand{
String nameAuthor
static hasMany = [books:Book]
static constraints = {
nameAuthor nullable:false
books nullable:false
}
}
Ps: I know that this commandObject is wrong, it don't compile. But can I do something like this ???

hasMany in GORM is used for association in Domain objects. In case of command objects it will be a lucid approach to have different command objects for each domain (for example: AuthorCommand and BookCommand) and the command object would look like:
import org.apache.commons.collections.list.LazyList
import org.apache.commons.collections.functors.InstantiateFactory
//Dont need this annotation if command object
//is in the same location as the controller
//By default its validateable
#grails.validation.Validateable
class AuthorCommand{
String nameAuthor
//static hasMany = [books:Book]
//Lazily initialized list for BookCommand
//which will be efficient based on the form submission.
List<BookCommand> books =
LazyList.decorate(new ArrayList(),
new InstantiateFactory(BookCommand.class))
static constraints = {
nameAuthor nullable:false
books nullable:false
//Let BookCommand do its validation,
//although you can have a custom validator to do some
//validation here.
}
}

Not sure why don't you can try like(normal hibernate hasMany declaration)
class MyValidateCommand{
String nameAuthor
Set<Book> books= new HashSet<Book>();
static constraints = {
nameAuthor nullable:false
books nullable:false
}
}

Related

Creating Domain Relationships in Grails returns unable to resolve class error

Good day to all. I am very new in using grails and I have followed several tutorials for beginners using grails until I come up in creating domain relationships. However, I got stuck with this problem right now. I have 3 domain classes namely, todo, category and user. And as I defined their relationships, it returns me an error saying unable to resolve class. Please see my codes below. Please help. Thank you so much.
Todo.groovy Class
package todoScaff
class Todo {
String name
String note
Date createDate
Date dueDate
Date completedDate
String priority
String status
User owner
Category category
static belongsTo = [User, Category]
static constraints = {
name(blank:false)
createDate()
priority()
status()
note(maxsize:1000, nullable:true)
completedDate(nullable:true)
dueDate(nullable:true)
}
String toString() {
name
}
}
Category.groovy Class
package categoryScaff
class Category {
String name
String description
User user
static belongsTo = User
static hasMany = [todos: Todo]
static constraints = {
name(blank:false)
}
String toString(){
name
}
}
User.groovy Class
package userScaff
class User {
String userName
String fname
String lname
static hasMany = [todos: Todo, categories: Category]
static constraints = {
userName(blank:false, unique:true)
fname(blank:false)
lname(blank:false)
}
String toString(){
"$lname, $fname"
}
}
Since you've placed your domain classes in different packages, you must import the classes at the head of the file.
package categoryScaff
import todoScaff.Todo
import userScaff.User
class Category {
The same needs to happen in your other domain classes that reference classes outside the current package.

Behaviour of belongsTo

What is the difference between
static belongsTo [author:Author]
and
static belongsTo = Author
Lets consider two domain class.
Class Author{
String name
}
Class Books{
String name
static belongsTo = Author
}
When static belongsTo = Author is kept in Books domain, it have no effects on db. However, static belongsTo = [author : Author] creates a backreference to Author class and also there is author_id column in db. So, what actually using static belongsTo = Author alone does.
This is expalined in grails docs(http://grails.github.io/grails-doc/latest/ref/Domain%20Classes/belongsTo.html).
Also, what is the difference between using following two :
Class Books{
String name
static belongsTo = [author : Author]
}
Class Books{
String name
Author author
}
static belongsTo = [author : Author] is used only for cascading purposes, Is it true or does it have different use cases.
Can anyone explain these in detail without relating it to hasOne or hasMany. Thanks in advance.
Using belongsTo without a back-reference is necessary for many-to-many associations. For example, lets assume you have the following domain classes:
class Book {
String name
Author author
static hasMany = [categories: Category]
}
class Category {
String name
static hasMany = [books: Book]
}
If you try to use them as-is you'd get an exception like this:
No owner defined between domain classes [class Book] and [class Category] in a many-to-many relationship. Example: static belongsTo = Category
The solution is to make one of the domain classes the owner of the many-to-many association. Using my example, I think it makes more sense to make the Category the owner. However, a back-reference would not work because there could be multiple Categorys. So, this is where a belongsTo without a back-reference comes in:
class Book {
String name
Author author
static hasMany = [categories: Category]
static belongsTo = Category
}
If you use static belongsTo = [author: Author] then a property named author of type Author is added to the class as a back reference. With static belongsTo = Author that does not happen.

How do you organize the fields in grails 2.4.4 including the static mapping relations?

Okay, so I understand how to organize the fields in grails without using the gsp pages by writing the fields in the constraints like so.
Class User{
String firstName;
String nickName;
static constraints = {}
}
this will make first name appear before nick name in the default scaffolding because f comes before n in the alphabet.
Class User{
String firstName;
String nickName;
static constraints = {
nickName()
firstName()
}
}
this makes nick name appear before first name in the CRUD model in scaffolding. It's the order you name the constraints.
Now, how do you make the relations appear in a specific order? For example if I had this
Class User{
String firstName;
String nickName;
static belongsTo = {company:Company}
static constraints = {
}
}
How would I rearrange this order? would it be done in constraints? I know it can be done in gsp page, but how would I do it here?
I'm pretty sure it's the same as regular fields...
i.e. if you want the order of the fields to appear as nickName, firstName, company you'd do this:
Class User {
String firstName
String nickName
static belongsTo = {company: Company}
static constraints = {
nickName()
firstName()
company()
}
}

grails: multiple belongsTo with back reference

Is it possible to have a domain class that belongs to multiple domain classes with back reference? For instance:
class Person {
List<Book> books
static hasMany = [books: Book]
}
class Organization {
List<Books> books
static hasMany = [books: Book]
}
class Book {
def owner // what's the type?
static belongsTo = [Person, Books]
}
A Book can belong to a Person or an Organization, but not both.
Person and Organization have separate sequence IDs.
The solution I came up with is:
class Book {
Long ownerID
String ownerClass
static belongsTo = [Person, Books]
static transients = ['owner']
static constraints = {
ownerId(nullable:false, blank:false)
ownerClass(nullable:false, blank:false)
}
public BookOwner getOwner() {
grailsApplication.getArtefact("Domain", ownerClass)?.getClazz()?.get(ownerId)
}
}
where BookOwner is an Interface implemented by Person and Organization. So calling a bookInstance.owner will return a Person or Organization instance, both BookOwner.
My solution works well, but it doesn't feel right - a sure sign that I am not fully understanding what I'm doing. What's the best way to implement this? Should I completely give up on having the extremely convenient back reference?
Thank you
I guess, you should have made Owner superclass. Grails will create Owner table with field class meaning child class names (in your case: Person, Organization).

Grails many-to-many relationship

I'm trying to do a many-to-many relationship on Grails 1.3.4 and I'm getting this exception:
Caused by: org.codehaus.groovy.grails.exceptions.GrailsDomainException: No owner defined between domain
classes [class gblog.Post] and [class gblog.Comentario] in a many-to-many relationship.
Example: static belongsTo = gblog.Comentario
The code for Comentario is:
package gblog
class Comentario {
static constraints = {
}
String conteudo
Date data
static belongsTo = [post:Post, autor:Usuario]
static hasMany = [posts:Post]
}
The code for Post is:
package gblog
class Post {
static constraints = {
}
String titulo
String conteudo
String palavrasChave
Date data
static belongsTo = [categoria:Categoria, autor:Usuario]
static hasMany = [comentarios:Comentario]
}
Thanks everybody!
I think Grails is getting confused here:
static belongsTo = [post:Post, autor: Usuario]
static hasMany = [posts:Post]
You might want to diagram how all of the classes are interacting, because I'm thinking that this is a little off.

Resources