I have three domain classes as follows :
Case {
...
Reserve reserve
...
}
Reserve {
...
Amount amount
...
}
Amount {
...
Double value
String currency
...
}
I have a createcriteria as follows
List<Case> cases = []
cases = Case.createCriteria().list( ) {
/* I want to access currency of each case here */
}
Is it possible to access value of Currency for each Case inside the createCriteria? I am new to grails and I tried looking for documentation for this but couldn't find any.
like #cfrick commented:
def cases = Case.createCriteria().list {
reserve {
amount {
eq('currency', 'EUR')
}
}
}
You can use sqlRestriction() to write native sql query inside createCriteria.
More info here
Related
When you have defined field as an union of two types (in example machines contains Ships and Droid) then in Relay you can do something like that:
fragment on Faction# relay(plural: true) {
name,
machines {
... on Ship {
name
}
... on Droid {
name,
primaryFunction
}
}
}
so under machines prop your objects are correctly evaluated, but if you want to do that using fragments from external components:
fragment on Faction# relay(plural: true) {
name,
machines {
${StarWarsShip.getFragment('ship')}
${StarWarsDroid.getFragment('droid')}
}
}
then you end up with fragment definitions under machines. It looks like you are trapped and can't check which object is which type in machines array so you can't decide which component should be used.
There exists a __typename field with which you should be able to introspect the type of each record:
Query
fragment on Faction #relay(plural: true) {
name,
machines {
__typename # <-- add this
${StarWarsShip.getFragment('ship')}
${StarWarsDroid.getFragment('droid')}
}
}
App code
this.props.faction.machines.map(machine =>
machine.__typename === 'Droid'
? <Droid droid={machine} />
: <Ship ship={machine} />
);
class Client {
String name
static hasMany = [courses:Course]
}
class Course {
String name
static belongsTo = [client:Client]
}
I have this and I want to get all Clients that has a Course with name = "blabla"
I was trying to do : Clients.findWhere(Course.any { course -> course.name = "math" })
You can do this with criteria:
Client.withCriteria {
courses {
eq('name', 'math')
}
}
I believe that the following where query is equivalent to the above criteria:
Client.where { courses.name == 'math' }
or you may find you need another closure:
Client.where {
courses {
name == 'math'
}
}
but I rarely use where queries myself so I'm not 100% sure of that.
There are probably a lot of different syntactical expressions to achieve the same thing. I can say definitively that this works in my project though.
def ls = Client.list {
courses {
eq('name','math')
}
}
I have a fairly large criteria closure in my Grails application, and I would like to reuse part of it in several places in my application. Rather than duplicating the section I need to reuse, I'd like to define this as a separate closure and reference it wherever it is needed, but I am struggling a bit with the syntax.
This is a simplified / cut down version, but essentially my criteria looks something like this:
def criteriaClosure = {
and {
// filtering criteria that I'd like to reuse in lots of places
or {
names.each { name ->
sqlRestriction(getFilteringSql(name), [someId])
}
}
if (isOrganisationChild(childDefaultGrailsDomainClass)) {
sqlRestriction(getFilteringSql(domain), [someArg])
}
// filtering criteria that's specific to this particular method
sqlRestriction(getSomeOtherSql(), [someOtherArg])
}
}
def criteria = domain.createCriteria()
def paginatedList = criteria.list([offset: offset, max: max], criteriaClosure)
I've tried defining the part of the closure I want to reuse as a variable, and referencing it in my criteria closure, however the restrictions it defines don't seem to be applied.
def reusableClosure = {
and {
or {
names.each { name ->
sqlRestriction(getFilteringSql(name), [someId])
}
}
if (isOrganisationChild(childDefaultGrailsDomainClass)) {
sqlRestriction(getFilteringSql(domain), [someArg])
}
}
}
def criteriaClosure = {
and {
reusableClosure() //this doesn't seem to work
sqlRestriction(getSomeOtherSql(), [someOtherArg])
}
}
I'm sure this must be a pretty straightforward thing to do, so apologies if it's a daft question. Any ideas?
I think you have to pass the delegate down to the reusableClosure, ie:
def criteriaClosure = {
and {
reusableClosure.delegate = delegate
reusableClosure()
sqlRestriction(getSomeOtherSql(), [someOtherArg])
}
}
Working in Grails 2.2
I have a situation where I need to be able to handle an unknown number of CommitteeMembers in the view. These need to be both created and displayed.
Each one has the usual attributes - name, address, contact information, userid.
I understand that if I name form fields the same name, Grails will return a collection for me to iterate over. In this case, however, I am faced with this situation:
cm_firstname
cm_lastname
cm_address
cm_email
cm_userid
So does this mean I will be given collections of each of these fields? That is not as useful as there is no way to corelate the various firstnames with the correct lastnames, etc.
I am enjoying Grails and am looking forward to your feedback.
You can use Grails Command objects to do this work for you. Here's an example in a SO question. Basically you will have a single collection of CommitteeMembers that will be populated in your controller thorugh data binding.
As #Gregg says, in the view you need the fields to have an index.
class MyDomain {
String name
}
class MyDomainCommand {
List<MyDomain> instances = ListUtils.lazyList([], FactoryUtils.instantiateFactory(MyDomain))
}
class MyController {
def save() {
MyDomainCommand command = new MyDomainCommand()
bindData(command, params, [include: 'instances'])
}
}
I'll tell you what I do, which may or may not be the best option. I do this mainly because I don't like data binding.
For your case as an example, I would name my fields: "cm.firstName, cm.lastName, cm.address, cm.email, cm.userId".
If you are in a service:
GrailsWebRequest webUtils = WebUtils.retrieveGrailsWebRequest()
List committeeMembers = [].withDefault {new GrailsParameterMap([:], webUtils.getCurrentRequest())}
In a controller:
List committeeMembers = [].withDefault {new GrailsParameterMap([:], request)}
Then
params.cm.each { k, v ->
if (v instanceof String[]) {
v.eachWithIndex { val, idx ->
committeeMembers[idx]."$k" = val
}
}
else {
committeeMembers[0]."$k" = v
}
}
Then you can do:
committeeMembers.each {
<Create from it.firstName, it.lastName, etc>
}
Assume a domain class called User. User class looks like this:
class User {
List<String> values
}
The collection values contains strings like "http://example.com/x", "http://google.com/y", "http://google.com/z" and so on...
Let's say we want to build a query which gets all the users that have specific string in the collection values (e.g. "google.com"). Something like this:
def criteria = User.createCriteria()
def results = criteria.listDistinct () {
and {
user.values.each { like('someField', '%${it}%') }
}
}
Any ideas?
I have found the answer by experimentation. The solution is:
def criteria = User.createCriteria()
def results = criteria.listDistinct () {
and {
user.values.each { like('someField', '%'+it+'%') }
}
}
I am not sure what you are doing with your suggested answer.
I have never seen that usage of each in the criteria query before.
This question has been asked many times before but never given an answer.
The problem is that you are queriyng a String association, which is not a domain class. If you would make your own String domain class for example ondrej.String { String strValue } then you would be able to do :
User.withCriteria {
values { ilike("strValue", "...") }
}
The problem is not having access to the value of the String object. The value of the String class is called value, but it is a char array, so I do not believe the following will work:
User.withCriteria {
values { ilike("value", "...") }
}
You could try using :
User.withCriteria {
values { ilike("toString", "...") }
}
or something else instead of toString ... I do not have the possibility to test this right now.
Hope that helps
After a lot of trying and researching, I found this will work with Grails 2.4.0, I don't know about older versions.
Cat.withCriteria {
createAlias('nicknames', 'n')
ilike 'n.elements', '%kitty%'
}
The trick is to use 'n.elements'