Share variable across domain and controller in grails - grails

can i have one variable shared between two classes in grails, like in my controller i want to set a variable processStart as true, and once the after save method is done in my domain class of that controller i want to set it false like this,
class EmployeeController{
def insert() {
for (i in 1..params.numberOfEmp.toInteger()) {
Employee emp = new Employee(params)
processStart = true // set this variable here
emp.save()
}
}
}
and in domain class
class Employee {
/** domain structure **/
def afterInsert () {
processStart = false // and after this, set this variable here
}
}

Try using a session variable, you shouldn't do this with a static variable.
class EmployeeController{
def insert() {
for (i in 1..params.numberOfEmp.toInteger()) {
Employee emp = new Employee(params)
session['processStart'] = true // set this variable here
emp.save()
}
}
}
and in domain class:
class Employee {
/** domain structure **/
def afterInsert () {
session['processStart'] = false // and after this, set this variable here
}
}

Related

How can I pass data between GSP and controller in Grails without storing in the database?

Is it possible to enter data in the GSP view and use this data in the controller inside the program to do some operations without storing this data in the domain. For example I have a g:textField and I enter my name. I want to be able to use the name that I enter in the controller to manipulate.
None of the data passed from a view to a controller has to line up with any particular Domain. There are a couple of ways you could do this.
the view:
<g:textField name="name" />
the controller:
class SomeController {
def someAction() {
def name = params.name
// do something with name
}
}
You could also use a Command Object.
the command object:
#Validateable
class SomeCommand {
String name
static constraints = {
name nullable: false
}
}
the controller:
class SomeController {
def someAction(SomeCommand someCommand) {
if (!someCommand.hasErrors()) {
def name = someCommand.name
// do something with name
}
}
}

Grails Reusable Service for saving Domain Objects

I have a Grails project with multiple Domain Classes, and I want to make a persistence service as reusable as possible by only having one save() inside of it. To try and achieve this I have done the following in my project.
//PersistenceService.groovy
#Transactional
class PersistenceService {
def create(Object object) {
object.save flush: true
object
}
//BaseRestfulController
class BaseRestfulController extends RestfulController {
def persistenceService
def save(Object object) {
persistenceService.create(object)
}
//BookController
class BookController extends BaseRestfulController {
private static final log = LogFactory.getLog(this)
static responseFormats = ['json', 'xml']
BookController() {
super(Book)
}
#Transactional
def save(Book book) {
log.debug("creating book")
super.save(book)
}
So basically I have a bunch of domains for example Author etc, each with their own controller similar to the bookController. So is there a way to reuse the service for persistence like I am trying above?
Thank you
I'm doing something similar, but mainly because all my entities are not actually removed from the database but rather "marked" as removed. For several apps you need such an approach since it's critical to prevent any kind of data loss.
Since most databases do not provide support for this scenario, you can't rely on foreign keys to remove dependent domain instances when removing a parent one.
So I have a base service class called GenericDomainService which has methods to save, delete (mark), undelete (unmark).
This service provides a basic implementation which can be applied to any domain.
class GenericDomainService {
def save( instance ) {
if( !instance || instance.hasErrors() || !instance.save( flush: true ) ) {
instance.errors.allErrors.each {
if( it instanceof org.springframework.validation.FieldError ) {
log.error "${it.objectName}.${it.field}: ${it.code} (${it.rejectedValue})"
}
else {
log.error it
}
}
return null
}
else {
return instance
}
}
def delete( instance, date = new Date() ) {
instance.dateDisabled = date
instance.save( validate: false, flush: true )
return null
}
def undelete( instance ) {
instance.dateDisabled = null
instance.save( validate: false, flush: true )
return null
}
}
Then, in my controller template I always declare two services: the generic plus the concrete (which may not exist):
def ${domainClass.propertyName}Service
def genericDomainService
Which would translate for a domain called Book into:
def bookService
def genericDomainService
Within the controller methods I use the service like:
def service = bookService ?: genericDomainService
service.save( instance )
Finally, the service for a given domain will inherit from this one providing (if needed) the custom logic for these actions:
class BookService extends GenericDomainService {
def delete( instance, date = new Date() ) {
BookReview.executeUpdate( "update BookReview b set b.dateDisabled = :date where b.book.id = :bookId and b.dateDisabled is null", [ date: date, bookId: instance.id ] )
super.delete( instance, date )
}
def undelete( instance ) {
BookReview.executeUpdate( "update BookReview b set b.dateDisabled = null where b.dateDisabled = :date and b.book.id = :bookId", [ date: instance.dateDisabled, bookId: instance.id ] )
super.undelete( instance )
}
}
Hope that helps.

Override delete() function in Grails Domain-Class

I have the following classes:
class User {
String name
}
class Book {
User user
}
I want that if I delete a User object, it also deletes the Book object containing the user instance. Since I have no relation from the User class to the book class cascade delete will not work.
I can write the Book class as:
class Book {
belongsTo = [user: User]
}
The former also does not do cascade delete because there is still no relation defined in the User class.
What I did is the following:
class User {
String name
def deleteUser() {
def books = Book.findAllByUser(this)
books.each { it.delete(flush: true) }
}
delete(flush: true)
}
I do not think that this is the best solution. What can I do instead? Is there a way to extend the User class delete() function somehow?
I tried the following but it fails.
def delete() {
def books = Book.findAllByUser(this)
books.each { it.delete(flush: true) }
}
super.delete(flush: true)
This is where business logic meets transactions inside of a Service class. Here is how I would do it, if I were using the relationship as you have defined it:
def UserService {
static transactional = true
def delete(Long userId) {
def user = User.get(userId)
def userBooks = Book.findAllByUser(user)
userBooks*.delete()
user.delete()
}
}
And then just call this service from the controller.
Arguably, if a book really does belong to a user, define both sides of the relationship, and it should cascade.

How to set model attribute for every action

earlier I use Spring MVC and annotation #ModelAttribute.
#Controller
public class ArticleController {
#ModelAttribute("articles")
public List<Testset> getArticles(){
return articleDao.all();
}
#RequestMapping("/first.htm")
public void first(){
}
}
How can made this behaviour in Grails controller?
class ArticleController{
//this variable I want to in every action
List articles
def first = { }
def second = { }
def third = { }
}
Of course I can use this code for every action
def first = {
this.articles = Article.all()
}
but I want not this.
Thank very much for your help.
Tomáš
You can define an after interceptor and add data to the model there:
class ArticleController {
def afterInterceptor = { model ->
model.articles = Article.list()
}
def first = { }
def second = { }
def third = { }
}
The docs for this are here: http://grails.org/doc/latest/ref/Controllers/afterInterceptor.html

Dependency Injection In Grails Domain Controllers

I'm trying to create a a custom constraint. I've put the logic in a service:
class RegExpManagerService {
boolean transactional = false
def messageSource
def lookupRegexp(regExpression,Locale locale) {
def pattern = messageSource.getMessage( regExpression,null,locale )
return pattern
}
def testRegexp(regExpression,text,Locale locale) {
return text ==~ lookupRegexp(regExpression,locale)
}
}
and tried to inject it in my domain controller:
class Tag extends IbidemBaseDomain {
def regExpManagerService
static hasMany=[itemTags:ItemTag]
static mapping = {
itemTags fetch:"join"
}
//Long id
Date dateCreated
Date lastUpdated
String tag
// Relation
Tagtype tagtype
// Relation
Customer customer
// Relation
Person updatedByPerson
// Relation
Person createdByPerson
static constraints = {
dateCreated(nullable: true)
lastUpdated(nullable: true)
tag(blank: false,validator: {val,obj ->
regExpManagerService.testRegexp(obj.tagtype.regexpression,val,local)
})
tagtype(nullable: true)
customer(nullable: true)
updatedByPerson(nullable: true)
createdByPerson(nullable: true)
}
String toString() {
return "${tag}"
}
}
When the constraint gets executed I get this error:
2009-08-24 18:50:53,562 [http-8080-1] ERROR errors.GrailsExceptionResolver - groovy.lang.MissingPropertyException: No such property: regExpManagerService for class: org.maflt.ibidem.Tag
org.codehaus.groovy.runtime.InvokerInvocationException: groovy.lang.MissingPropertyException: No such property: regExpManagerService for class: org.maflt.ibidem.Tag
The constraints closure is static, so it can't see the instance field 'regExpManagerService'. But you have the object being validated so you can access it from that:
tag(blank: false,validator: {val,obj ->
obj.regExpManagerService.testRegexp(obj.tagtype.regexpression,val,local)
})

Resources