I'm trying to get all the Users that are born today with GORM but I'm failing to write this query in Grails:
SELECT
DAY(dateOfBirth) AS 'day',
MONTH(dateOfBirth) AS 'month'
FROM Users
WHERE day = '...' AND month = '...';
... will be replaced with today's values.
Minimal User Domain class
class User {
Date dateOfBirth
...
}
Minimal UserService class
#Transactional
class UserService {
def getTodayBirthdays() {
def bornTodayQuery = User.where{
/* I'm thinking here I must
* select the DAY and MONTH from the DB
* and compare it with the today ones.
*/
}
User usersBornToday = bornTodayQuery.findAll()
usersBornToday
}
}
Any ideas how can I do an alias (SELECT field AS alias) with GORM?
I'm using:
Grails 2.4.4
Thanks!
You could use a where query in your service:
#Transactional(readOnly = true)
def listBirthday(int _month, int _day) {
// Calendar.JANUARY equals to zero!
def m = _month + 1
// Run a where query on the users
User.where {
month(dateOfBirth) == m && day(dateOfBirth) == _day
}
}
#Transactional(readOnly = true)
def listBirthdayToday() {
def cal = Calendar.getInstance()
listBirthday(cal.get(cal.MONTH), cal.get(cal.DAY_OF_MONTH))
}
In addition to month and day there are some other functions, here is the documentation (look for "Other Functions")
Any ideas how can I do an alias (SELECT field AS alias) with GORM?
(SELECT field AS _alias)
Putting an underscore (_) as prefix to alias worked for me with grails-2.5.6
I have not found it in documentation but using trail and error method.
Related
I'm trying to get the list of a specific rental from the current user.
Code in controller:
def index() {
if (isLoggedIn()) {
String username = getPrincipal().username
def accountInstance = Account.findByUsername(username)
def rentalInstanceList = Rental.findAll("from Rental as r where r.account_id=:accountid", [accountid: accountInstance.id])
}
}
account_id is a foreign key.
After running I get the error:
could not resolve property: account_id of: ers.Rental
What am I doing wrong?
Generally, in HQL you have to use the field names as defined in your domain classes. So, your query should look like:
def list = Rental.findAll("from Rental where accountId=:accountid", [accountid: accountInstance.id])
or
def list = Rental.findAllByAccount accountInstance
or even
def list = Rental.findAllByAccount getPrincipal()
if the return type of getPrincipal() has the id field.
findAll is not limited to instances of the calling class so I use executeQuery instead. https://stackoverflow.com/a/8916483/5011228
So I have the domain class as follows:
class Enrollment {
Course course
Date date
User user
static constraints = {
}
}
In my controller, I have this action :
def persons = Enrollment.list(fetch :[user : "a"])
render persons
I am trying to fetch only a user named "a" and its corresponding map. But it displays all..I tried FindAllWhere but throws an error
No such property: user for class: tester.EnrollmentController
I am assuming that the User class has a name property.
What about:
def user = User.findByName("a")
def persons = user ? Enrollment.findAllByUser(user) : []
Assuming here that you can find a unique user (name probably isn't unique enough), otherwise I would do something like:
def persons = Enrollment.createCriteria().list{
user {
eq('name', "a")
}
}
A have class Product:
class Product {
static hasMany = [attributeValues: ProductAttributeValue]
String productId
String manufacturer
BigDecimal price
static constraints = {
productId unique: true, blank: false
manufacturer blank: false
price min: BigDecimal.ZERO
}
}
I want to find all products, which productId contains substring 'filter'.
I wrote next code:
Product.findAll {it.productId.contains(filter)}
But it doesn't work. Why?
this should't work at all!
you have 2 options here:
1) you use propper GORM techniques like criteria query or HQL, the would look like:
Product.findAllByProductIdIlike( "%${filter}%" ) // dyn-finders
Product.withCriteria{ ilike 'productId', "%${filter}%" } // criteria
Product.findAll{ ilike 'productId', "%${filter}%" } // criteria
Product.findAll( "from Product where productId like '%?%'", [ filter ] ) // hql`
2) or use filtering on the whole dataset in grails app's memory (instead of the db) - NOT recommended:
Product.list().findAll{ it.productId.contains(filter) }
You can use regex,
Try this :
def yourProductIsWithFilter = '123filter456'
def matchingPattern = 'filter'
//def patternToMatch = /\b${matchingPattern}/\b
//def patternToMatch = /[A-Z_0-9${matchingPattern}/]
def patternToMatch = ~/.${matchingPattern}/
Product.findAll{it.productId =~ patternToMatch }
Note: I haven't tested the code.
Hope it gives you a heads up.
Regards
I have a domain class Project as below
class Project {
String projectName
String projectCode
String techLead
String projectManager
Date deliveryDate
String currentPhase
Integer priority
}
I have controller as below
class ProjectController {
def scaffold = Project
def index = {
redirect(action:list,params:params)
}
def list = {
// displays only 10 records per page
if (!params.max) params.max = 10
[ projectList: Project.list( params ) ]
}
}
I would like to display the list of projects in the sorting order or priority. How can I implement that ?
change your list action to the below
def list = {
// displays only 10 records per page
if (!params.max) {
params.max = 10
}
params.sort = "priority"
params.order = "asc" // change to "desc" to sort in the opposite direction
[projectList: Project.list(params)]
}
A much shorter and more idiomatic way of doing this would be to use the dynamic methods on list that provide ordering:
def list = {
[projectList: Project.listOrderByPriority(max: params.max ?: 10)]
}
I'm working on a small event calendar and i want to sort the events by start time!
I'm using JodaTime Plugin in grails for the startTime attribute. ( http://www.grails.org/JodaTime+Plugin )
So, how can i sort with this datatype? This does not work:
def sortedEvents = events.asList().sort({ a, b -> a.startTime <=> b.startTime } as Comparator)
I hope you can help me!
Thanks,
whitenexx
/EDIT/
This is the code where i'm getting the events:
def getEventsNext(Location location) {
def events = location.events.findAll { it.endTime >= new DateTime() }
def sortedEvents = events.sort{it.startTime}
System.out.println(sortedEvents); //test
return sortedEvents
}
In /event/list action everything works fine with g:sortableColumn (sorting by startTime):
Try this:
def sortedEvents = events.asList().sort{it.startTime}
To reverse the sorting order, use:
def sortedEvents = events.asList().sort{-it.startTime}
FYI, Groovy adds this sort() method to Collection so you can remove asList() from the code above if events is already a Collection.
Try overriding the compareTo method in your domain classes.
For example,
int compareTo(obj) {
startTime.compareTo(obj.startTime)
}
Edit
Sort your events like so:
def sortedEvents = events.sort{e1,e2-> e1.startTime.compareTo(2.startTime)}
Or as suggested by #Don, the groovier equivalent
def sortedEvents = events.sort{e1,e2-> e1.startTime <=> e2.startTime}
Try
def events = location.events.findAll { it.endTime.isAfterNow() }
def sortedEvents = events.sort{it.startTime.toDate()}
JavaDoc for isAfterNow()