Grails CRUD list order by a field - grails

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)]
}

Related

How to compare collection item using createCriteria?

Registration domain has a collection of discounts.
static hasMany = [ discounts: Discount]
I want to extract all Registrations that have a particular discount applied.
In the following code i want to get all registrations whose collection has the discount of id disid. How can i achieve that? I appreciate any help!
def disid = Discount.get(1).id
def regs = Registration.createCriteria().list(){
eq('compositeEvent', cod.compositeEvent)
}
Try this:
def disid = Discount.get(1).id
def regs = Registration.withCriteria() {
discounts {
eq 'id', disid
}
}
See http://emmanuelrosa.com/articles/gorm-for-sqladdicts-where-clause/

GORM findAll doesn't work

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

how can I read values from groovy g:select in my controller

I have several g:selects in my gsp that I want to use for filtering a query. How can I access their values in the controller? Here is a select that I have:
<td><g:select name="accts" from="${accountSelection}"/></td>
Here is how I populate the list
def filter() {
def allaccts = getAccountSelection()
[accountInstanceList:allaccts.accountInstanceList]
}
def getAccountSelection() {
params.max = 10
def accts = []
accts.add("all")
Account.list().each { item -> accts.add(item) }
[accountInstanceList: accts, accountInstanceTotal: Account.count()]
}
In your controller it's just another parameter. You can access it like this:
params?.accts?.each {
println it
}

Why I get a cannot cast object 'null' error, when testing my controller?

I have a controller like this :
def unCompletedTasks() {
def user = User.get(springSecurityService.principal.id)
def choice = params.managersProject
params.max = Math.min(params.max ? params.int('max') : 10,100)
def search = Tasks.createCriteria().list(max: params.max as Integer, offset: params.offset as Integer, order: params.order as String, sort : params.sort) {
and {
project {
like('name',"${choice}")
}
eq('completed',false)
lt('endDate',new Date().clearTime())
}
}
[tasksInstanceList : search, tasksInstanceTotal: search.getTotalCount() ]
}
I want to test this. I wrote a test specification in Spock like this:
def 'user should be displayed unCompletedTasks' () {
setup: "set the required objects"
def tasksController = new TasksController()
tasksController.springSecurityService = [principal: [id:tasksInstance.id]]
tasksController.params.managersProject = "testing"
//other codings goes here
when:
def model = tasksController.unCompletedTasks()
then:
model.tasksInstanceTotal == 1
where:
//required fields
}
When I run, I get a error like this :
user should be displayed unCompletedTasks(mnm.schedule.TasksSpec)
| org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'null' with class 'org.codehaus.groovy.runtime.NullObject' to class 'java.lang.Integer'
at mnm.schedule.TasksController.unCompletedTasks(TasksController.groovy:39)
at mnm.schedule.TasksSpec.user should be displayed unCompletedTasks(TasksSpec.groovy:59)
I don't know where I went wrong.
Thanks in advance.
Sounds like the same problem as discussed in Problems casting a null object with Spock. The solution is to upgrade to Grails 2.0.2.

How to save multiple rows of data by looping through an array or a map?

Class Buyer {
String name
static constraints = {
}
}
Class Order {
String ref
static belongsTo = [buyer:Buyer]
static constraints = {
buyer(nullable:false)
}
}
In OrderController.groovy
...
def someAction = {
//working
def data1 = ["buyer.id": 2, "ref": "xyz"]
def ord = new Order(data1);
ord.save();
def data2 = ["buyer.id": 2, "ref": "234xyz"]
def ord2 = new Order(data2);
ord2.save();
//But in a loop - its not working
def items = ['abc', 'def', 'ghi', 'jkl']
def data2 = [:]
for(e in items) {
data2 = ["buyer.id": 2, "ref" : e.value] //keeping buyer id same
def ord = new Order(data2);
ord.save();
data2 = [:] //just emptying it?
}
}
As you would notice in "working" above, if I am able to save multiple rows by copy pasting and definging new maps but If I try to loop through an array, it doesnt work. Any ideas how do I save data by looping through an array or a map?
Any questions, please let know
Thanks
First, I'm not sure about ["buyer.id": 2, "ref" : e.value], I think it should be [buyer: Buyer.get(2), ref : e.value].
Second, I would recommend using cascading save to do the task. You can try something like this(You need to define a static hasMany = [orders: Order] relation in Buyer for Buyer-Order relationship.
Buyer b = new Buyer(name: "foo")
for(e in items) {
def ord = new Order(ref: e.value);
b.addToOrders(ord)
}
b.save(flush:true)
You should just be able to do:
def someAction = {
def items = ['abc', 'def', 'ghi', 'jkl']
items.each { item ->
def ord = new Order( [ 'buyer.id':2, ref:item ] )
ord.save()
}
}
What errors (if any) are you getting?
Also, why are you doing e.value? This will get you an array of Character rather than a String (which is what your first working example is using)

Resources