I have a problem in a grails application. My application use a plugin to generate some domain models, I need to add a field to one of those domain models and I don't have the source code. Is there a way to do it dynamically? For example using the GORM API the metaclass or something like that?
You could probably just extend the class from the plugin and add your field. That is a common thing to do with plugins like Spring Security Core.
class MyUser extends SecUser {
String phoneNumber
...
}
Related
In grails 4 (grails 3+), we have to mark the domain classes with multi tenant trait and also its respective services and controllers.
For eg :
class Book implements MultiTenant<Book> {
String title
}
#CurrentTenant
class BookService {
#WithoutTenant
int countBooks() {
Book.count()
}
}
Is there a configuration for gorm to make everything as multi tenant? My requirement is, based on domain name for eg: abc.com or xyz.com where tenants are abc and xyz i need to switch database but i don't want to go on to annotate each domain class and controllers.
Is there a configuration for gorm to make everything as multi tenant?
No.
You have options like you could build an AST transformation that would do such a thing, but no feature like that exists in the framework itself.
I wonder if you can use Shiro-Plugin for Grails without having permissions and roles enabled?
In our current Project, we have an external database with just username and password and I am not able to create the permissions and roles table.
Is there a way to implement one Shiro user with automatic permission to all Domains without role-management?
From Shioro plugin documentation
Create a class in src/groovy or src/java that implements the grails.plugin.springsecurity.shiro.ShiroPermissionResolver interface, and define the
Set<String> resolvePermissions(String username)
method any way you like. Register your bean as the shiroPermissionResolver bean in resources.groovy, for example
import com.mycompany.myapp.MyShiroPermissionResolver
beans = {
shiroPermissionResolver(MyShiroPermissionResolver)
}
Given these functional requirements:
User Management
Administrator
Librarian
Borrower
*The users have the option of logging-in via OpenID.
Property Management
Book
Memorandum
Circular
License
Normally, I would implement these in Java as:
interface User {}
class Librarian implements User {}
class Administrator implements User {}
class Borrower implements User {}
class OpenID {} //all Users HAS AN OpenID attribute (NULL if non-openId login)
interface Property{}
class Book implements Property{}
class Memorandum implements Property{}
class Circular implements Property{}
class License implements Property{}
But our project will use Groovy & Grails, which I haven't experience using yet. My question is,
how should the domain classes be designed based on the requirements above? I can't use an interface, and it seems inheritance is not a good practice. My idea is to use composition, though I'm quite bothered by the database tables that would be generated. What are the best practices in this situation?
Well first of all lets correct it, you can use inheritance in this case. You just need to change the convention of has a relationship to is a relationship.
Few factors to keep note of:
1. Grails works on convention over configuration.
2. You can use GORM which wraps the persistence layer and creates an Object Mapping for the underlying persistence layer with the help of Hibernate.
As per your functional requirement:-
If you do not want to have the User as part of persistence you can have an abstract class User which can hold the common properties of the User including the openId attribute. It has to be placed in src\groovy directory as per convention (since the base class is abstract, dependency injection will be defied)
The same goes for Property. Abstract Property class in src\groovy.
Now coming to the business models, extend each of the concrete entities (domain classes) from the abstract parent.
Summary:-
Create grails app
Under src\groovy(for example, I am considering a basic structure):
User.groovy:-
abstract class User{
String name
String emailId
OpenID openId
}
Property.groovy:-
abstract class Property{
String propertyName
}
Under grails-app/domain:
Librariran.groovy:-
class Librarian extends User{
//Attributes specific to Librariran
static constraints = {
}
static mapping = {
}
}
Book.groovy:-
class Book extends Property{
//Attributes specific to Book
static constraints = {
}
static mapping = {
}
}
So on and so forth. Groovy objects under grails-app/domain are considered concrete entities by Grails convention. More information you can obviously find here. You can also use composition if you come across scenarios, in fact I already mentioned that in User having OpenId.
Note:- This is context to latest version of Grails (> 2.x)
I have a class called LoginCommand in domain/my/package/name
class LoginCommand {
String emailAddress
String password
}
My question is why is a table be auto generated in my database for a ***Command object in grails? Are these command objects supposed to be placed ouside of /domain to avoid auto generation of a table by hibernate/orm.
They should not go in grails-app/domain; they are not domain classes. Place them in src/groovy. Alternatively, a common convention is to put the command class in the same file as the controller that uses it.
Take a look at the Convention Over Configuration section in the grails manual to get an idea of what goes where.
I am trying to inject 'GraauditService' into grails 'User' domain class.
I am using grails 1.3.7
I have tried direct injection method as I do in controllers
import com.gra.audit.GraauditService
class User {
def graauditService // or even GraauditService graauditService with graauditService as transient
.......
the above does not work. graauditService is always coming up as null
I also tried to inject through ApplicationHolder as shown here
But looks like ApplicationHolder is deprecated now
How can I use the service in the domain class?
The following works for me
class User {
def springSecurityService
static transients = ['springSecurityService']
}
Try injecting it using the transient keyword:
class User {
transient graauditService
}
For Grails 1.3.7, the solution is to inject it through the ApplicationHolder, as shown here by Burt Beckwith.
The above solutions may work for Grails 2.0, but not for 1.3.7 or earlier.