Errors trying to search a many to many relationship in grails - grails

I'm having trouble contructing a query within an many to many relationship... I have these domain classes:
class Event {
Appuser creator
static belongsTo = Appuser
static hasMany = [guests: Appuser]
and
class Appuser {
static hasMany = [friends: Appuser, events: Event]
So the idea is a user can have friends, and they can set up and own multiple events, and they can also be guests of other user's events.
My issue is constructing a query to get the list of guests for a particular event...
I've tried in my controller:
def guests = Appuser.findAllByEvent(eventInstance)
this gives an error
No property found for name [event] for class
def guests = Appuser.findAllByEvents(eventInstance)
this gives an error
No value specified for parameter 1
Any ideas how to remedy? Thanks.

Appuser.findAllByEvent doesn't make sense because there's no event property in the class. Dynamic finders can only work with persistent properties. findAllByEvents is more likely to work because there is an events property (added by an AST transform because of the hasMany) but you can't query on collections with dynamic finders; you need to use criteria/where/HQL queries for those.
But you don't need a query at all - just use the hasMany property you declared:
Event eventInstance = ...
def guests = eventInstance.guests

Related

Grails - Querying a domain instance's properties' properties

So far all the examples of queries I am coming across are geared towards a domain class such as:
Account.where, Account.withCriteria, Account.findxxxx but what if I want to query an instance's properties' properties? For example what if I have c a company instance that has a department d and I want to get a list of all the departments of this company instance that have 12 employees (a property of department) or less? What would be the code for such a query?
Something like:
c.findAllD's(such that d.numberOfEmployees <= 12)
Also, can anyone point me to literature on such instance based queries? I haven't been able to come across it.
The easiest approach would be to make the association bidirectional, i.e.
class Company {
static hasMany = [departments:Department]
}
class Department {
Company company
int numberOfEmployees
static belongsTo = [company:Company]
}
Then you can simply start your queries from the Department end, such as
def c = Company.get(...) // or however you obtain your Company instance
def departments = Department.findAllByCompanyAndNumberOfEmployeesLessThanEquals(c, 12)
looks like you want to use the Named Queries

Creating one-to-many & many-to-many for same domain class in grails

I want to create a domain class as like , One user can post many orders [Bidirectional] and one order can be liked by many users [unidirectional].
I have written a domain class as shown below ,
Class User {
String userName;
List orders
static hasMany = [Order]
}
Class Order {
String orderId
String orderName
//Indicates this order belongs to only one user
static belongsTo =[owner : User ] // Bidirectional
//Indicates order can be liked by many users
static hasMany = [likedUser : User] //Unidirectional
}
But I am getting am error saying invalid schema . Any body please help...
This post looks similar to my question but I am not getting , Please help.
First, order is a reserved word in SQL. Since GORM by default creates a table with the same name as your class, you'll need to either rename your class or provide a different name to use when mapping to SQL tables.
For example:
class Order {
static mapping = {
table 'user_order'
}
// ...
}
Another problem is that Order contains two associations to User. You need to tell GORM which one of these that is the bi-directional association from User to Order. That can be achieved using mappedBy, like this:
class User {
String userName
static hasMany = [orders: Order]
static mappedBy = [orders: 'owner']
}
Hope this helps.

Unidirectional Many To One mapping with cascade

Is it possible to map the following with GORM?
I want to get rid off all associated events when I delete a person.
Person object should not have a link to events.( I want to avoid using hasMany on Person domain)
class Person {
String username
}
class Event {
String description
static belongsTo = [person:Person]
}
I'm getting now a 'Referential integrity constraint violation' when doing person.delete() because events are not removed before deleting person.
I don't think that is possible without using hasMany (speaking of which, why do you want to avoid that anyway?)
This SO Question states:
Hibernate only cascades along the defined associations. If A knows
nothing about Bs, nothing you do with A will affect Bs.
Use static hasMany and bam, problem fixed.
Edit:
The only way I think you could achieve this is using beforeDelete on the Person class to delete all the associated Events, i.e.
class Person {
def beforeDelete() {
def events = Event.findAllByPerson(this)
for (e in events) {
e.delete()
}
}
}
See the documentation on Events and Auto Timestamping for more info on that.
The above will not work
Why not define a no reference mapping:
class Person {
String username
static hasMany=[Events]
}
This way there is no actual bindings of events to person but a person can have many events

Need some explanation to understand how Grails works

I'm new to Grails, some things are still vague for me.
I want to create a Twitter-like app. As a user has both a followers and a following groups, I've created a GroupMyTwitter domain.
What I don't understand, is the logic behind this. My GroupMyTwitter domain is like this :
class GroupMyTwitter
{
String name;
static constraints = { name blank : false; }
static hasMany = [users:UserMyTwitter];
static belongsTo = [owner:UserMyTwitter];
}
Then every time I create a user I also create two groups associated to him :
GroupMyTwitter followers = new GroupMyTwitter (
name:"followers",
owner: user).save(flush: true, failOnError: true)
// And same for followings
Now I simply wonder... how can I access these groups to get the followers/ings count, add or delete some?
Thanks for your help.
Based on the hasMany and belongsTo variables gorm automatically creates some instance fields for you:
static hasMany = [users:UserMyTwitter];
This will create a field users of type Set inside GroupMyTwitter.
You can access this Set like any other field:
followers.users.add(userA) // add a user
followers.users.remove(userB) // remove a user
followers.users.size() // number of users
// don't forget to save the group after you modfied the `users` collection:
followers.save(failOnError: true)
Depending on your needs it might be useful to use a List instead of a Set:
class GroupMyTwitter {
List users
static hasMany = [users:UserMyTwitter];
...
}
This causes Gorm to use a List for the users collection instead of a Set.
A List has a defined order and allows you to access certain elements by index:
UserMyTwitter user = followers.users[4] // get the 5th user

Sorting query results according to parent property in grails

Is it possible in grails to sort query results according to a property of a parent class in a relationship. E.g. I have a user domain class which has a one to many relationship with a list of Tasks.
When showing the list page of the Tasks domain class, I want to be able to sort the list of tasks by the associated User name.
class User {
String name
String login
String group
List tasks = new ArrayList()
static hasMany = [tasks:Task]
}
class Task {
String summary
String details
User user
static belongsTo = [user:User]
}
I can do something like this
Task.list([sort:"user", order:"asc"])
But this sorts by the user.id, is there a way to specify the sort to be on the user.name?
You can do it using Criteria
def criteria = Task.createCriteria()
def taskList = criteria.list {
createAlias("user","_user")
order( "_user.name")
}
iirc, grails sorts by using toString() and since you have not supplied one, it uses the id.

Resources