I have the domain classes TestUnit, TestParameter and ParameterRange as shown below.
class TestUnit {
static hasMany = [testParameters : TestParameter]
}
class TestParameter {
static hasMany = [paramRanges : ParameterRange ]
static belongsTo = [testUnit : TestUnit]
}
class ParameterRange {
static belongsTo = [testParam : TestParameter]
}
I want to add the TestUnit object (i.e, testUnitInstance.id) in the ParameterRangeController.
Since i'm new to grails i don't know how to do that could anyone please explain it to me?
What I've tried:
def testUnitId = params.testUnitId
def testUnitInstance = TestUnit.get(testUnitId)
def testParameterInstance = TestParameter.get(params.id)
[parameterRangeInstanceList: testParameterInstance.paramRanges, parameterRangeInstance: new ParameterRange(),testParameterInstance:testParameterInstance, page:"Range", testUnitInstance:testUnitInstance]
You can manipulate more than one domain class in a controller or service, there's no restriction to that.
class ParameterRangeController {
def show() {
//you can get other domain classes...
TestUnit theUnit = TestUnit.get(1)
render view: 'show', model: [theUnit:theUnit, ...]
}
}
Since TestUnit is related to TestParameter, you can also access it like:
ParameterRange range = ParameterRange.get(1)
println range.testParam.testUnit
I suggest you to take a look in the docs about GORM, there's a lot of useful info.
Related
I'm new to Grails. I'm having problem with retrieving data from DB. I have domains with classes, something like...
class Lightbox {
String name = ''
String link = ''
static hasMany = [users: LightboxUserAccount]
}
class LightboxUserAccount {
UserAccount userAccount
static belongsTo = [lightbox: Lightbox]
}
class UserAccount {
String username
...
}
I want to list all "Lightboxes" owned by user with ID=4. I was trying
def my_lb = Lightbox.findAll("from Lightbox as lb where lb.users=:userAccount", [userAccount: springSecurityService.getCurrentUser()])
or
def my_lb = Lightbox.findAllByUsers(4)
None of those work for me. What am I doing wrong? Thx
Try this one:
Lightbox.findAll("from Lightbox as lb where :userAccount in (lb.users)", [userAccount: springSecurityService.getCurrentUser()])
So I did it slightly different, using criteria instead. Take a look if interested
static getAllByUserAccount(UserAccount userAccount) {
def criteria = Lightbox.createCriteria()
def my_lb = criteria.list {
users {
eq('userAccount', userAccount)
}
}
return my_lb
}
It seems to be working. Thanks for responses though
I've two domain classes
1.CustomerInterest.groovy
static hasMany = [activities:Activity]
static belongsTo=[customer:Customer,projectProperty:ProjectProperty]
static mapping={
activities sort:'dateCreated',order:'desc'
}
2.Activity.groovy
Date dateCreated
static belongsTo = [customerInterest:CustomerInterest, employee:Employee]
In a controller i am doing this..
def customerDetails(Customer customer)
{
def customerInterest=customer.customerInterests
render view:"customerDetails",model:[customerInterest:customerInterest]
}
customerDetails.gsp
<g:each in="${customerInterest}" var="ci">
${ci}
</g:each>
**
Question: I want to sort CustomerInterest on property dateCreated of Activity domain.
**
Any help as soon as possible would be appreciated.
Try this
def customerInterest=customer.customerInterests.sort { it.activities.dateCreated }
Instead of using the sort order in the mappings definition, you can use the old java Comparable-interface:
class Foo implements Comparable {
int compareTo(anotherObject) {
// complex logic returning -1 or 0 or 1
}
}
Then you can call listOfFoos.sort() and it will sort it with the help of the compareTo-method.
Beware that (equals) == will also use this method, so ensure that (only) identical objects will return 0.
Say I have a domain Books.
static hasMany = [reader:Reader]
And Class Reader
String fullName
Now I want to add Readers with fullName: "PersonA", "PersonB", "PersonC" by defualt in the Books domain.
Please tell how do I accomplish this? I am pretty new with Grails.
You can create class named BootStrap in Configuration folder of your App andd add init() method to it. This method will be executed before App starts. Example:
class BootStrap {
def init() {
def readerA = Reader.findOrCreateByFullName("PersonA")
def readerB = Reader.findOrCreateByFullName("PersonB")
def readerC = Reader.findOrCreateByFullName("PersonC")
def readers = [readerA, readerB, readerC]
def book = new Book()
for(reader in readers){
book.addToReader(reader)
}
book.save(flush: true)
}
}
I am trying to write a query in Grails to return a set of results from a domain class, but within those return the relevant results of a separate class whom have the parentId of the main class.
def query = Cars.where {
(colour == 'red')
}
And then within each list item include the set of parts relating to that CAR ID (as an example of what I'm trying to achieve, I know the code is incorrect though....
query.each{
this car. add(Parts.whereCarID{it.id})
}
If you define your domain model properly, you should get it without a criteria involved.
As far as I understand you need to add static hasMany = [parts: Parts] in your Cars domain class, and static belongsTo = [car:Cars] in your Parts class.
So for example, here how it might look:
class Cars {
string colour
static hasMany = [parts:Parts]
// ... rest of your properties
}
class Parts {
static belongsTo = [car:Cars]
// ... rest of your properties
}
And to get your result just do this:
def cars = Cars.findAllByColour('red')
Then you can do:
cars.each { car->
println car.parts // <-- all the parts for each car is here
}
I have static method in a domain class that returns a url. I need to build that url dynamically but g.link isn't working.
static Map options() {
// ...
def url = g.link( controller: "Foo", action: "bar" )
// ...
}
I get the following errors:
Apparent variable 'g' was found in a static scope but doesn't refer to a local variable, static field or class. Possible causes:
You attempted to reference a variable in the binding or an instance variable from a static context.
You misspelled a classname or statically imported field. Please check the spelling.
You attempted to use a method 'g' but left out brackets in a place not allowed by the grammar.
# line 17, column 19.
def url = g.link( controller: "Foo", action: "bar" )
^
1 error
Obviously my problem is that I am trying to access g from static context, so how do I get around this?
The g object is a taglib, which is not available inside a domain class like it would be in a controller. You can get at it through the grailsApplication as shown here: How To Call A Taglib As A Function In A Domain Class
A better way to do this in Grails 2+ is through the grailsLinkGenerator service, like so:
def grailsLinkGenerator
def someMethod() {
def url = grailsLinkGenerator.link(controller: 'foo', action: 'bar')
}
In both cases, you'll need to do some extra work to get grailsApplication/grailsLinkGenerator from a static context. The best way is probably to grab it off the domainClass property of your domain class:
def grailsApplication = new MyDomain().domainClass.grailsApplication
def grailsLinkGenerator = new MyDomain().domainClass.grailsApplication.mainContext.grailsLinkGenerator
If you're using Grails 2.x you can use the LinkGenerator API. Here's an example, I am re-using a domain class I was testing with earlier so ignore the non-url related functionality.
class Parent {
String pName
static hasMany = [children:Child]
static constraints = {
}
static transients = ['grailsLinkGenerator']
static Map options() {
def linkGen = ContextUtil.getLinkGenerator();
return ['url':linkGen.link(controller: 'test', action: 'index')]
}
}
Utility Class with Static Method
#Singleton
class ContextUtil implements ApplicationContextAware {
private ApplicationContext context
void setApplicationContext(ApplicationContext context) {
this.context = context
}
static LinkGenerator getLinkGenerator() {
getInstance().context.getBean("grailsLinkGenerator")
}
}
Bean Def for New Utility Bean
beans = {
contextUtil(ContextUtil) { bean ->
bean.factoryMethod = 'getInstance'
}
}
If you need the base URL, add absolute:true to the link call.