grails grom create criteria with many-to-many mapping - grails

I have two domain classes: User and Book.
class Book implements Serializable{
String bookName
Timestamp createdDateTime
Blob file
static belongsTo = [User]
static hasMany = [user :User]
}
I am able to add user in book using addToUser() method.
But I am stuck in create criteria while applying filter in user.
def query = Book.createCriteria();
def results = query.list () {
eq("user",userObject) // not working since user field is a list of users.
order("createdDateTime", "desc")
}
Please help me with the correct way of filtering.

You need to join the user table first in a many-to-many relation. The criteria should look like:
Book.withCriteria {
user {
eq("id", userObject.id)
}
order("createdDateTime", "desc")
}

I'm not 100% sure how you're trying to model your domain but maybe you want a Book to have a single user? In which case you'd have the belongsTo relationship on Book e.g.
class Book {
String bookName
Timestamp createdDateTime
Blob file
static belongsTo = [user: User]
}
Then have the hasMany relationship on User e.g.
class User {
String name
static hasMany = [books: Book]
}
Then you can look Books up with criteria like:
def user = User.findByName( 'bob' )
def results = Book.createCriteria().list () {
eq( "user", user )
order( "createdDateTime", "desc" )
}

Related

Grails: HIbernate-filter - Adding filter on mapped class column

I want to use grails hibernate filter plugin to add a filter on of my domain class.
http://grails.org/plugin/hibernate-filter
Domain classes:
class Movie {
String name
String genre
String yearOfRelease
boolean deleted
}
class EditRequest {
String reason
String requester
Date requestDate
String status //can be 'PENDING', 'ONHOLD', OR 'COMPLETE'
static belongsTo = [
movie: Movie,
requester: User
]
}
There could be multiple edit request for a movie.
I have an API where I need to display all edit requests for all non-deleted movies.
How do I add hibernateFilter for non-deleted movies in my EditRequest domain class
I tried below in my EditRequest class, but non of them works.
1.
static hibernateFilters = {
deletedMovieFilter(condition:'deleted=false', default:true)
deletedMovieFilter(collection:'movie', default: true)
}
2.
static hibernateFilters = {
deletedMovieFilter(condition: 'deleted = false')
deletedMovieFilter(collection: 'movie', joinTable: true)
}

Equals object criteria query

If I have two domain classes like this:
class Company{
string Name
string address
}
class User {
string firstName
string lastName
Company company
}
How can I get all the users from company named Google using criteria query? Something like this:
def company = Company.findByName("Google")
def c = User.createCriteria()
def usersByCompany = c.list {
eq("company", company)
}
You can declare a block inside your closure to filter any field in the Company:
def usersOfGoogle = User.createCriteria().list() {
company {
eq('name', 'Google')
}
}
I just don't remember if it works only for relationships (belongsTo & hasMany), maybe you will need to change your domain class:
class User {
static belongsTo = [company : Company]
}

Grails criteria select when hasMany hasn't any elements

I have the classes:
class Course{
String name
static hasMany = [
studentGrades: StudentGrade
]
}
class StudentGrade{
String name
int grade
}
How can I make a criteria to get the courses without any student grade?
You could use the isEmpty criterion method:
def c = Course.createCriteria()
def results = c.list {
isEmpty("studentGrades")
}
See the docs for further informations.

Grails: Paging and Sorting over the collection in a relationship

I'd like to do paging and sorting from a collection in a relationship
For example with the following model:
class User {
String userName, password
static hasMany = [roles: UserRole, preferences: Preference]
}
class UserRole {
String name, description
static hasMany = [actions: Action]
}
I'd like to recover all the roles for a specific user. I already have the user loaded so the normal way to do it would be using
user.roles
But I want to sort them by UserRole properties and I want to paginate them dynamically
I know that if I want to get all the UserRoles sorted and paginated I can use:
UserRole.list([sort: 'name', order: 'asc',max: 5,offset:0])
But I want to do it just for the roles that are associated to my user. I was trying to use criteria, but I think I'm missing something.
I also had a look here:
http://grails.1312388.n4.nabble.com/A-Relationship-Paging-Pattern-td1326643.html
But then I would have to add the relation back into UserRole so I would have:
static hasMany = [users : UserRole]
How can I do this? what would be the best way?
Please, let me know if you need more information and sorry if I wasn't clear enough
Thanks and regards
You cannot paginate an "ordinary" relationship.
You can change the order child objects appear in using mapping DSL:
static mapping = {
sort name:desc
}
To simplify a hand-crafted paginated relationship, you can use a named query:
class Role {
static namedQueries = {
userRoles {
eq('user', UserSessionService.instance.currentUser)
}
}
}
Or you can implement a transient User's property that will return a Criteria for User's Roles (which can be paginated).
Grails Pagination with hasmany relation Bidirectional property finally i come to the point were i found it working Huuuh.
These are the Domain classes
class Client {
List bills
String shopName
String nameOfClient
static hasMany = [bills: Bill]
static constraints = {
shopName(blank:true, nullable:true)
nameOfClient(blank:false, nullable:false)
}
}
class Bill {
String billDetails
String billNo
static belongsTo = [client: Client]
static constraints = {
billDetails(blank:true, nullable:true , type: 'text')
billNo(blank:true, nullable:true)
}
}
Now This is my controller Logic
def clientDetails(){
def maxJobs = 4
def offset = (params?.offset) ?: 0
def clientId = params.id
def bills = Client.get(clientId).bills
def client= Client.get(clientId)
def results = Bill.withCriteria {
eq('client', client)
firstResult(offset as Integer)
maxResults(maxJobs)
}
[id:client.id,bills: results, offset: offset, max: maxJobs, totalJobs: bills.size()]
}
And the gsp code
<g:each in="${bills}">
<tr>
<td>${it.billNo}</td>
<td>${it.billDetails}</td>
</tr>
</g:each>
<g:paginate class="pagination" controller="client" action="clientDetails" total="${totalJobs?:0}" offset="${offset}" max="${max}" params="[id:"${id}"]"
prev="« Previous" next="Next »" />

How to model a Friend - Friendship relationship in Grails

How would you model a friend - friendship relationship in Grails? Until now my User class had many followers
class User {
//Searchable plugin
static searchable = true
String userId
String password
boolean enabled = true
// For Spring Security plugin's user registration.
String email
String userRealName
boolean emailShow
Date dateCreated
Profile profile
static hasMany = [
posts : Post,
tags : Tag,
following : User,
authorities : Role,
notifications: Notification,
locations: Location,
incomingLocations:IncomingLocation,
]
static belongsTo = Role
static constraints = {
userId(blank: false, size:3..20, unique: true)
password(blank: false)
dateCreated()
profile(nullable: true)
userRealName(nullable: true, blank: true)
email(nullable: true, blank: true)
}
static mapping = {
profile lazy:false
}
}
But I would like to change the following:User for something like friendships:Friendship and create a Friendship class as following:
class Friendship {
static belongsTo= [user:User]
User friend2
boolean areFriends
}
Is this an ideal implementation?
How would you implement the handshake (accept/reject a pending friendship)?
You might not need to model Friendship directly. You can just have a hasMany relationship that relates the Users as friends. You don't create that relationship until someone accepts a FriendRequest. If they no longer want to be friends, then just remove the relationship between the 2 Users.
class User {
static hasMany = [friends:User]
}
class FriendRequest {
User fromUser
User toUser
}
That way Friendship doesn't have to do 2 things (relate users and track statuses). And friends becomes a natural object relationship which can make some things like optimizing fetching a bit easier.

Resources