How to set model attribute for every action - grails

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

Related

Grails controllers and inheritance/closures

Grails 2.4.4 here. All of my controllers were generated using the standard grails create-controller ... command:
class FizzController {
def index() {
// ...
}
}
class BuzzController {
def index() {
// ...
}
}
...etc.
At the top of each action method, in each controller, I need to call a method doSomething(String). This method needs to have access to redirect(...) so that it can redirect the user if need be. Ideally, I could create an abstract base controller class and have all my controllers extend it:
abstract class BaseController {
void doSomething(String cmd) {
if(cmd == 'Yee haw!') {
redirect(controller: 'foo', action: 'baz')
return false
}
}
}
class FizzController extends BaseController {
def index() {
String cmd = getCmdSomehow()
doSomething(cmd)
// ...etc.
}
}
class BuzzController extends BaseController {
def index() {
String cmd = getCmdSomehow()
doSomething(cmd)
// ...etc.
}
}
However I'm not sure Grails will allow this, since it's doing "Groovy magic" under the hood to make sure there is access to things like redirect(...) and render(...), etc. It would also be wonderful if I could put all this in a closure and just have it executed implicitly (without having to call doSomething() at the beginning of each and every controller action.
What is my best option/solution here? Please use a concrete code example!
Use Filter instead:
class ExampleFilters {
def filters = {
logFilter(controller: '*', action: '*') {
before = {
}
after = { Map model ->
}
afterView = {
}
}
}
}

Grails get list of A's where searching with B's in many to many relationship

I have the following domain objects:
class Blog {
String foo
}
class Comment {
String bar
}
class BlogComment {
Blog blog
Comment comment
}
So far I've written this:
def getComments(Blog blog) {
def blogCommentCriteria = BlogComment.createCriteria()
def blogCommentResults = blogCommentCriteria.list {
eq 'blog.id', blog.id
}
List<Comment> comments = new Vector<Blog>()
blogCommentResults.each { i ->
if(i.blog == blog) {
comments.add(i.comment)
}
}
comments
}
What would be the most efficient method? I want the method to be clean and simple, but also efficient in terms of time taken.
You can add a method to the Blog class to get the comments associated with a given blog:
class Blog {
String foo
def getComments() {
BlogComment.findAllByBlog(this)*.comment
}
}

Grails 2.2.0 URLMappings: Any way to use same URL with Different Verb

I have the following:
"/api/users"(controller: "user") {
action = [GET:"list"]
}
Doing a call to http://localhost:8080/platform/users I get a list of users back. Then I added this:
"/api/users"(controller: "user") {
action = [POST:"save"]
}
And now I get a 404 and it is not hitting either method in UserController. I'd like to be able to use the same URL with the verb controlling which action. Am I doing this wrong or does Grails not support this?
From the Grails docs: URL Mappings
static mappings = {
"/product/$id"(controller:"product") {
action = [GET:"show", PUT:"update", DELETE:"delete", POST:"save"]
}
}
For your case:
"/api/users"(controller: "user") {
action = [GET:"list",POST:"save"]
}
Check your userController to see if there is allowedMethods defined accordingly like this:
class UserController {
static allowedMethods = [save: "POST", list: "GET"]
def list() {
.....
}
def save() {
.....
}
}

Null when injecting SpringSecurityService into Filter in Grails

I'm trying to use SpringSecurityService in a filter to get currently logged in user. The problem is that I got null and cannot get the current user.
class ApplicationFilters {
def springSecurityService
def filters = {
all(controller:'*', action:'*') {
after = { Map model ->
def userName=springSecurityService.currentUser
}
}
}
}
I tried also to get params map from the filter and I got also null. What should I do to solve this?
Thanks,
don't know if you've solved this issue yet, but you can definitely call your Service within the *Filters class by referring to the injected applicationContext like this:
class TestFilters {
def filters = {
all(controller:'*', action:'*') {
before = {
applicationContext.testService.serviceMethod()
}
after = { Map model ->
}
afterView = { Exception e ->
}
}
}
}

Grails controllers repeated code for all actions

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.

Resources