Grails controllers repeated code for all actions - grails

Imagine this controller:
class exampleController{
def action1 = {}
def action2 = {}
def action3 = {}
def action4 = {}
def action5 = {}
}
I want to be able to return in all the action in this controller the same params. Imagining this:
def user = session.user
[user: user]
Is there any way of doing this, besides writing all the same code on all the actions? The session.user return params is just an example. I don't wanna really return it.

A simple solution is to put this code in a method and call it from each action
class exampleController{
def action1 = {getModel()}
def action2 = {getModel()}
def action3 = {getModel()}
def action4 = {getModel()}
def action5 = {getModel()}
private getModel() {
def user = session.user
[user: user]
}
}
While this does involve some amount of repetition (invocation of the same method), it's a lot more obvious what's happening here. When debugging/testing a controller it's easy to forget about filters and interceptors, which can often lead to questions like
what the #**% is going on here?

Use a filter - http://grails.org/doc/latest/guide/6.%20The%20Web%20Layer.html#6.6%20Filters - or an after interceptor - http://grails.org/doc/latest/guide/6.%20The%20Web%20Layer.html#6.1.5%20Controller%20Interceptors

I have a similar case, and I was modified the grails scaffolding for the controller's generator.
class MyClassController {
def list = {
...
}
def show = {
def eInstance = beanIfExist()
...
}
def edit = {
def eInstance = beanIfExist()
...
}
def update = {
def eInstance = beanIfExist()
...
}
def delete = {
def eInstance = beanIfExist()
...
}
def beanIfExist = {
def beanInstance = MyClass.get(params.id)
if (beanInstance) {
return beanInstance
} else {
flash.message = "Error, invalid record."
redirect(action: "list")
return null
}
}
}
It is my suggestion, now if do you need another that sent a data to view then you can use interceptors.

Related

Map single controller to multiple methods/action

My Controller name is ...Login...
and method/action names like....HomeContent.....automotive...etc
I am also posting my controller code here..
class LoginController {
def dataSource;
static allowedMethod = [userLogin:"POST",HomeContent:"GET",Disclaimer:"GET",FAQ:"GET",OurTeam:"GET",ourPortfolio:"GET",privacyPolicy:"GET",beautyTips:"GET",dietNutrition:"GET",healthFitness:"GET",yoga:"GET",mentalStress:"GET",automotive:"GET",digitalMarketing:"GET",ecommerce:"GET",education:"GET",finance:"GET",foodAndBeverage:"GET",marketUpdates:"GET",realState:"GET",coWorkingSpaces:"GET",homeRemodeling:"GET",scienceAndTechnology:"GET",sportsMania:"GET",travelAndTourism:"GET",boxOffice:"GET",dayToDayNewsUpdates:"GET",mediaGossip:"GET",poertyZone:"GET",lifestyleMagazine:"GET",becomeAContributor:"GET"]
def HomeContent()
{
def query ="SELECT id,post_title,post_date,post_content FROM wp_posts where post_status='publish' and post_type='post' ORDER BY post_date DESC limit 10"
def db = new Sql(dataSource)
def json = db.rows(query)
render json as JSON
}
// About Us section starts here
def Disclaimer()
{
def query = "select distinct id,post_title,post_date,post_content from wp_posts where post_title='disclaimer' and post_status='publish'"
def db = new Sql(dataSource)
def json = db.rows(query)
render json as JSON
}
def FAQ()
{
def query = "select distinct id,post_title,post_date,post_content from wp_posts where post_title='FAQ' and post_status='publish'"
def db = new Sql(dataSource)
def json = db.rows(query)
render json as JSON
}
and my URLMapping code here..
class UrlMappings {
static mappings = {
"/Login"(controller:"Login",action:"HomeContent")
"/"(view:"/index")
"500"(view:'/error')
}
}
Add generic support to UrlMappings, assuming that's all you want:
//inside static mappings:
"/$controller/$action?"{ }

Grails actions getting called twice

The getStarted action redirects to companyInfo action which renders companyInfo.gsp and immediately after the page rendering, companyInfo action getting called one more time. I don't understand what the problem is.
class MyController {
#Secured('ROLE_USER')
def getStarted(){
def renderParams = [view: 'getStarted', model: [:]]
if(request.method != 'POST') {
render(view: 'getStarted')
} else {
def company = new Company()
.......
redirect(action: 'companyInfo', params: [id: company.id])
}
}
#Secured('ROLE_USER')
def companyInfo() {
def renderParams = [view: 'companyInfo', model: [:]]
if (request.method != 'POST') {
renderParams.model.cmpId = params?.id
render(renderParams)
}
}
}
See this answer. Grails trys to map get* to properties. And when the controller is called grails tries to map getStarted to a property called started, calling the method. So, Never Use get**** as your action name

cannot set readonly property:params

i'm trying to save a picture and return it's visit-url,but system throw a exception about params: 'cannot set readonly property: params'
def upload() {
def attachmentInstance = new Attachment(utype:params.type, udata:params.data)
if (!attachmentInstance.save(flush: true)) {
render(view: "create", model: [attachmentInstance: attachmentInstance])
return
}
def subMap = [url:"${createLink(controller:'attachment', action:'renderImg', params:'[id:${attachmentInstance.id}]')}", width:0, height:0]
def jsonMap = [id:attachmentInstance.id, type:"image", thumbnail:"", data:subMap]
def result = [result:jsonMap]
render result as JSON
}
It looks a little over-complex, can you try:
def subMap = [url:createLink(controller:'attachment', action:'renderImg', params:[id:attachmentInstance.id]), width:0, height:0]

grails question (sample 1 of Grails To Action book) problem with Controller and Service

I'm doing Grails To Action sample for chapter one. Every was just fine until I started to work with Services. When I run the app I have the following error:
groovy.lang.MissingPropertyException: No such property: quoteService for class: qotd.QuoteController
at qotd.QuoteController$_closure3.doCall(QuoteController.groovy:14)
at qotd.QuoteController$_closure3.doCall(QuoteController.groovy)
at java.lang.Thread.run(Thread.java:619)
Here is my groovie QuoteService class, which has an error within the definition of GetStaticQuote (ERROR: Groovy:unable to resolve class Quote)
package qotd
class QuoteService {
boolean transactional = false
def getRandomQuote() {
def allQuotes = Quote.list()
def randomQuote = null
if (allQuotes.size() > 0) {
def randomIdx = new Random().nextInt(allQuotes.size())
randomQuote = allQuotes[randomIdx]
} else {
randomQuote = getStaticQuote()
}
return randomQuote
}
def getStaticQuote() {
return new Quote(author: "Anonymous",content: "Real Programmers Don't eat quiche")
}
}
Eclipse show me an error flag on the definition of getStaticQuote:
ERROR: Groovy:unable to resolve class Quote
Any Clues?
Controller groovie class
package qotd
class QuoteController {
def index = {
redirect(action: random)
}
def home = {
render "<h1>Real Programmers do not each quiche!</h1>"
}
def random = {
def randomQuote = quoteService.getRandomQuote()
[ quote : randomQuote ]
}
def ajaxRandom = {
def randomQuote = quoteService.getRandomQuote()
render "<q>${randomQuote.content}</q>" +
"<p>${randomQuote.author}</p>"
}
}
Quote Class:
package qotd
class Quote {
String content
String author
Date created = new Date()
static constraints = {
author(blank:false)
content(maxSize:1000, blank:false)
}
}
I'm doing the samples using STS. Any advice?
Regards,
Francisco
do
def quoteService
at the top of your controller and it will be injected into the controller automatically
groovy.lang.MissingPropertyException: No such property: quoteService for class: qotd.QuoteController
I dont code in grails but it appears as though you need to declare quoteService somewhere in the controller.
I did
def quoteService = new QuoteService()
and it solved my problem

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

Resources