I have created several controllers in my Grails project and put data for each controller in the bootstrap, but the data does not appear in the table for each controller that scaffold provides as the default view. I have checked inside dbconsole to be certain that the data is there, which it is. I have also refreshed the dependencies to make certain that the version of the scaffolding plugin is not corrupted. I am using Grails 2.3.5 and Scaffolding 2.0.1.Are there any suggestions of what could be wrong?
class DepartmentController {
static scaffold=Department
def index() { }
}
Looking back at other examples of using scaffolding I realize now that I should have taken out the index portion of the code, even though it is empty.
Remove your the index method and make it like this:
class DepartmentController {
static scaffold=Department
}
Put some log messages into the controllers (or debug the app) right after the controller loads the data using the domain class in order to see if the query has resulted in any domain instances.
If not, activate sql logging and check the exact select statement executed. Possibly you have something wrong in your domain mapping so a wrong select stmt is sent to the db
Related
I am trying to write a custom src/templates/scaffolding/Controller.groovy and was wondering if there was any way to get access to the controller name? Right now it seems like you can only get the "model" class. The reason I need it is I am customizing the render to prefix the templates directory based on the controller.
For instance I have a controller named AuthorAdminController and I need to customize the list to use the /admin/user/** directory.
Let me know if you have any questions. I am getting ready to look into how to customize DefaultGrailsTemplateGenerator but I am not sure if that is the correct route to go.
Example:
class UserAdminController {
static scaffold = User
}
Currently in my Controller.groovy I get className='user' so I have no access to the controller.
I don't think you can, as the way scaffolding works your template will always be generating a class named DomainClassNameController (i.e. UserController in your example), which gets loaded into a new classloader and then the metaclass of the real controller (UserAdminController) gets new actions added to it which delegate to an instance of the generated UserController.
Now every controller has access to the controllerName property during execution of actions, so this may provide you with a workaround. I haven't tried it, but you could try putting a log.info("controller: \${controllerName}") into the template and see which name it gives you (the backslash to make it resolve at runtime rather than generation time).
Somehow I have gotten sideways with my Grails MVC mapping and I do not understand how.
I have a controller, AController, which I generated using the Grails command line wizard. At a later date I generated a view for that controller to customize the view.
AController is in [project]/grails-app/controllers/[package]/AController.groovy and the view .gsp's are in [project]/grails-app/views/A/.
The URLMappings.groovy has:
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
When I run the application and enter a url of the form: localhost:8080/[project]/A/list I reach, as expected, the method A.list in AController.groovy.
However, when I then return from A.list expecting the framework to route to list.gsp in [project]grails-app/views/A/ I see a 500 error with the message:
"URL mapping must either provide a controller or view name to map to!"
Obviously I am doing something stupid but I cannot see what it was that I broke. URLMappings.groovy looks correct. File locations look correct. Scaffolding seems properly customized.
Any suggestions?
Du-Oh
The problem was that there was no .count for an array. For some reason my brain insists on .count and not .size(). Stupid human error.
I'm having the strangest problem with a controller in a Grails project. I am trying to do a simple update of a domain object. Here is a simplified version of the controller
def updateRecord = {
def foundHVT = Process.get(params.hvt)
foundHVT.summaryBy = params.summaryBy
foundHVT.catalogBy = params.catalogBy
foundHVT.editBy = params.editBy
foundHVT.produceBy = params.produceBy
foundHVT.correctedBy = params.correctedBy
// a bunch more of these
foundHVT.save(flush: true);
redirect (action:resource, id: params.hvt)
}
If I run the a new instance of the application of and use this controller to update an object, it doesn't work, the object doesn't save. It will look fine within the controller. I can, for example, re-query the object and the changes are there, post save.
Now here's where it gets weird. If i use the preset scaffold edit controller and update/save an domain object -- and then switch back to this "updateRecord" controller it works FINE until i shut down the server it is working on?!?
I realize I am missing something very basic, but I can't find what it is. Any guidance would be most graciously appreciated.
DM
As HVGOTCODES noted Grails Clean seems to have fixed whatever weirdness was going on with this controller.
try putting a "def scaffold=true" in your controller if it does not already have the normal entry points.
Probably scaffolding save fills some field that you don't.
Possible problems:
Do check save() result and render foundHVT.errors the way Grails does. Add failOnError: true parameter to save() or just check foundHVT.hasErrors(). Look at foundHVT.errors.allErrors for validation problems.
Why not foundHVT.properties = params?
What is there is no foundHVT?
i am using subsonic 3.0 and active record with a mysql database
now everything is fine, but i cant seem to create views see example:
public ActionResult Index()
{
return View(contact.GetPaged(1,20));
}
now normally i would right click and choose Add View
i would then choose strongly typed and find the class for the repositary
however for some reason the only classes i get showing up are for subsonic only
but expect to see the new class from the new generated graniteMysqlDB
if anyone could please advice i would be most grateful as there doesent seem to be
any forum links or anything for subsonic.
thanks
okay i have solved the problem, but the answer is here should anyone need it or wants to know what happened.
i put my TT files into the models folder, my namesspace should have been test2.Models
however it was test2
also i needed the using directive of using test2.Models; at the top of my page.
still get an error where i have to correct the view on the inherites it puts
i have to change this to
very nice now is this subsonic very very fast loading compared to other stuff i have used.
ta
We are beginning the process of moving from Web Forms to MVC for all of our new applications. I am working on porting our Master Page over and am trying to satisfy the requirements that we need a single master page to be used by all applications. The primary navigation for the application needs to be in a menu within the master page. Accomplishing this was easy, the hard part is that each application may need to determine what to display in the menu using a unique set of rules. Some apps can simply say, here's the menu structure to use via something like a SiteMap. Others need to determine what is displayed in the menu based on what roles the user has, this can also be handled easily with a SiteMap. The situation that I'm struggling with is that some apps need to generate the menus based on the roles the user has, but also on the data on which they are working. i.e. The same user may have different option in the menu for a page if they are working on object 'foo' than they do if working on object 'bar'.
What I've done at this point, is I've created an HtmlHelper that is called by the master page view and takes a list of objects of a custom type and returns an unordered list that is styled by a jQuery plugin to display the menu. The list of objects the helper method takes are passed to the view using the ViewData dictionary. Currently, the value of this ViewData node is set within the constructor of each controller. This allows each page, and potentially each method, to set a different menu without having to set the value in each action method, unless its needed. I have also created a class that parses a SiteMap and returns the list of items needed to build the menu. This class is what I'm using to set the ViewData value in the controller. The idea being that if an application needed more control of how the menu data was generated, they could create their own class to generate the data as long as it returns a list of the correct type of objects.
This solution seems to work fine so far, it just doesn't 'feel' right for some reason. I'm hoping that I can either get some ideas of better way to do this or some reassurance that this is a valid approach to solving this problem.
If it is something that will be on every page, do something like this:
Create a base controller:
public class MyBaseController : Controller
Have this controller get the data it needs and send that data in the ViewData["menu"] to the View. Then have all your controllers inherit from this one:
public class HomeController : MyBaseController
In the Master Page, loop through your ViewData and create your menu.
(I did something like this for my sub-menu which displayed a list of categories.)
In the book I am reading (Pro ASP.NET MVC Framework by Apress) they use Html.RenderAction for the menu in the masterpage. I am a Asp.net MVC novice so maybe somebody else can give more info about this.
You can download the sourcecode at apress.com though so maybe that could help.