For example, I read in book that if we created relationship 1:m, Grails automatically add methods addTo* and removeTo*
and now i think, how i can see all methods my domain class?
for example, some like this: Domain.getAllMethods()?
Look at the Grails Documentation on the left pane under Domain.
While Domain.metaClass.methods will give you the list, you're going to need actual documentation behind how they work.
This can be done easily via the metaclass:
println Domain.metaClass.methods
Related
I'm very new to the Grails framework, so please bear with me.
Nonetheless, I am a bit confused on the functionality difference between extending a domain class and embedding objects.
From a database point of view, they both do the same thing. When embedding an object, all the properties of all the classes are stored in one table. Similarily, when extending a class (using table-per-hierarchy), all the properties of all the classes are stored in one table.
I'm sure there is a functionality difference between these two, and so I figured I ask this question.
When do you use either one?
The only technical difference is the ability to have multiple tables through the table per subclass property when extending a class. Otherwise, they are identical in use.
However, that said, by extending another class you are also modeling that within the class structure so you can make use of instanceof and polymorphic features of Java/Groovy.
I have problems to check if a persistent property in grails has an specific annotation for fields that belong to superclass ... ane then get it's name and value.
I am getting the persistence properties as:
GrailsDomainClassProperty[] persistentProperties = new DefaultGrailsDomainClass(entityClass).getPersistentProperties();
That works great ... but later i found that getDeclaredFields only retrieves the actual class fields (not superclass) and things starts to look not very Groovy.
Is there a prefered Groovy way to do this?
No, you should use this code for all super classes. The same will be for children classes.
According to the documentation, a Grails controller is simply a class with "Controller" appended to the name and saved in grails-app/controllers/. The simplest of such a class being:
package some.package
class FooController {
def index = {}
}
When the Grails application is run, this controller will inherit some standard methods like getParams and getSession. From the attached screenshot I can see that these are added via groovy.lang.ExpandoMetaClass. What I don't see is how this happens. The controller doesn't implement any interfaces or extend any abstractions. Where do these methods come from?
From Grails 2.0 a new methodology was adapted to add the dynamic methods to the controller artefacts. You can visit them step wise to see how those properties are added to Controllers:-
Controller in grails is not part of grails-core but a plugin by itself to grails named grails-plugin-controllers.
Being a plugin, the corresponding *GrailsPlugin Class would define the behavior of the plugin.
ControllersApi (extending CommonWebApi) bears all those properties which are to added to controller artefact. (Introduced from Grails 2.0)
ControllerGrailsPlugin registers ControllersApi as a spring bean.
There is more to just adding ControllerApi as a bean.
There is a concept of MetaClassEnhancer which would take/consider an API (in this case ControllerApi) and enhance/reconcile the artefact (controller) with the corresponding API by adding CachedMethods to the artefact using reflection, which is the role of a BaseApiProvider present in grails-core.
This magic happens in the Controller plugin class as well.
Now, prior to Grails 2.0 a different method was adapted to add the dynamic properties to controller. That way metaClass properties were added to controllers at runtime which was found to be less efficient. Each of the dynamic property was represented by its own class (viz: GetParamsDynamicProperty, GetSessionDynamicProperty) which is not in use right now.
So what you need to look now in the object tree for those dynamic methods is this where the CachedMethods are available in the controller. Hope that helps. I would be glad to add more if you seek more. :-)
You are right, Grails 'Controllers' are not really Controllers in the sense they inherit from a base class, but rather they are just simple POGOs that follow the convention of being placed in the grails-app/controllers directory. When your application is compiled, 30+ methods are mixed in through AST transformations, the majority of them coming from
org.codehaus.groovy.grails.plugins.web.api.ControllersApi, but also from
org.codehaus.groovy.grails.plugins.converters.api.ConvertersControllersApi,
org.codehaus.groovy.grails.plugins.web.api.ControllersMimeTypesApi.
The preceding was paraphrased from Programming Grails by Burt Beckwith, and I would recommend it if you are interested in the finer details of Grails.
Quoting from Burt Beckwith's excellent book, Programming Grails:
Over 30 methods are mixed into controller classes with AST
transformations. The majority are added from the
org.codehaus.groovy.grails.plugins.web.api.ControllersApi class
ControllersApi source
Where should I place a transient domain class in a grails app?
Ie I have an Action class that will be passed about, and used, but never saved. Should this be in the grails-app/domain folder, or somewhere else?
grails-app/domain is for persistent domain classes, but not all of your application's domain-related classes need to be there, e.g. in this case where you want to use it as a value object. You can put these in src/groovy along with other classes that aren't considered Grails artifacts.
If you want the classes to support validation, you can annotate them with #Validateable - see section "7.5 Validation Non Domain and Command Object Classes" in the ref docs: http://grails.org/doc/latest/
I think a CommandObject may fit the bill. These typically go in the same directory as your controllers, have the same validation features available to domain objects, but are never persisted. Great for things like search forms.
I'm trying to define a "Product"-class for my model (.edmx), and I have it in the same folder as the model.
I get: Ambiguity between 'MVCTest.Models.Product.ProductID' and 'MVCTest.Models.Product.ProductID' error
What's needed to do so I can define my classes correctly?
/M
Have you tried using "Partial class"? Only really appropriate if it's an extension of the product class I guess.
If this is not what you were looking for then let us know with more information or even code snippets.
You could always separate out by namespace. Have one class in one namespace. Although having the same class with the same properties is a bit unusual, and suggests that you need to refactor and create some form of inheritance as griegs suggested.