Viewing category: Grails Controllers
![]() ![]() Friday, 31 July 2009
![]() Book - Grails 1.1 Web Application Development - Part 9
![]() Chapter 8 - More GORM and Criteria
Part 1 of this series can be seen here. Part 2 of this series can be seen here. Part 3 of this series can be seen here. Part 4 of this series can be seen here. Part 5 of this series can be seen here. Part 6 of this series can be seen here. Part 7 of this series can be seen here. Part 8 of this series can be seen here. Chapter 8 builds upon our application by adding file versioning capability to our file sharing system. This provides the excuse to revisit GORM and criteria queries as promised in an earlier chapter. As we start the chapter, file sharing is modeled through two domains, File and FileData in a 1:1 relationship. Here we add FileVersion. FileVersion takes on all the responsibilities that File had, while File creates a hasMany property for the versions. In order to achieve the capability of retrieving the versions in the desired order, the author added a SortedSet property using the same name as the container specified in the hasMany map for the versions. In order to allow this ordering, FileVersion had to implement the Comparable interface and a compareTo method. Jon used the public access modifier on the compareTo method, which is unnecessary in Grails. It was nice having implementation of an ordered relationship between the two domains. After the requisite changes and additions were made, File is 1:m to FileVersion, and FileVersion is 1:1 to FileData. With this change, it became necessary to change how data was retrieved on the home page. This lead to the discussion of criteria queries. The first thing the author did was to show three dynamic queries from chapter 5 and the equivalent versions written using criteria. This clearly demonstrated how criteria queries are built. He then explains that nodes within the criteria can be used to specify logical operators and to query across associations. For the latter, a property added to File meant to hold a reference to the current FileVersion was used in demonstration. He also discussed the use of FetchMode as we still want to retrieve the User eagerly from the current version. After providing two tables, one a criteria reference, the other a listing of logical criteria operators, we are shown the use of criteria properties, in this case, limiting the results of our File query to ten. He closes the discussion of criteria queries by providing links to the Hibernate Criteria Javadoc, and informing us of and providing links to documentation on Projections and Scrollable Results. At this point, we are directed to modify the save method in the FileController. Here we run into a problem. The code listing on page 160 meant to display the errors does not work. In the listing, a view of post is referenced. No post view has been created thus far, nor is it contained in the downloaded source. The downloaded source references create as expected. Worse, though, is that by changing the model here from file to currentVersion breaks causes no messages to be displayed on an upload error. The problem is that the save is done on the File object and the Error object is bound to that, not to currentVersion. There are multiple solutions to this. One possible solution is to add a line just before the render to set the current version error object to the file error object. This is shown below. if (file.save()) { However, this smells to me. Rather, the preferred change in my opinion is to the create.gsp. Here the code currently reads: < g:hasErrors bean="${file}" > Change this to: < g:hasErrors > After writing the rather complex save logic in the controller, Jon tells us that he understands it is complex and difficult to test. He states that we will be moving much of this logic to a service in the chapter. The chapter is closes with the required changes to our home page and message properties, and by updating the download method in the FileController. I have to admit to being a bit frustrated by the errors encountered, though most books do seem to have some problems. None encountered so far have been insurmountable to me, but a noob may be really dazed and confused. Then again, problem solving is a great way to learn. If you feel that way, I suggest you download the free version of Jason Rudolph's mini-book Getting Started with Grails available at InfoQ, which was based on very early version of Grails and Groovy. ![]()
Rate this article
Read more | 0 comments ![]()
Posted by Bill Turner
at 08:53 PM
![]() Link directly to this article.
![]() ![]() Thursday, 2 July 2009
![]() Book - Grails 1.1 Web Application Development - Part 4
![]() Chapter 3 - Posting Messages
Part 1 of this series can be seen here. Part 2 of this series can be seen here. Part 3 of this series can be seen here. The beginnings of the business goals of the project are implemented with this chapter. We create a new domain, Message, two views, one for adding messages, the other for viewing, along with corresponding controllers. Along the way, we learn about binding, validation and other user messages, the flash scope, redirection, the domain list method, several gsp (Groovy Server Pages) tags, layouts including the main.gsp and how SiteMesh renders layouts, and securing the site from XSS (cross site scripting) attacks. There were a few small mistatements or errors. First, when explaining how dateCreated and lastUpdated properties can be added to domains and will be updated for free, he states that they must have the corresponding constraints set to nullable:true. The corresponding example shows this, as well. Setting these properties to null is unnecessary. To be fair, this could've been true in an earlier release of Grails. The second issue is really minor. At one point Jon suggests you use the BootStrap.groovy to create some initial messages then says you can view the home page and see these messages. What he fails to mention is that the application needs to be restarted to pick up the changes to the BootStrap.groovy (unless that was just some strange issue on my side, but I think not). The final error was when HTML encoding was discussed. We are instructed to make the highlighted changes, though the code sample has no highlighting. I trust experienced developers can overcome this. In earlier chapters we were introduced to some command line arguments for creating domains and controllers. In this chapter, however, we are never introduced to generate-views. I thought this curious. Yes, generate-views would create several unneeded views, but I feel this being an introductory text, it would be better to demonstrate the command and direct the reader to delete the unnecessary views. The positive side of having the reader hand code the views is that it makes it far more obvious how various code fragments relate to the other parts of the application, as well as the introduced GSP tags. At the end of this chapter, the reader should now have an understanding of the basic building blocks of Grails. This chapter covered a lot of territory. Even so, it seemed simpler than the previous chapter, likely because domain development is so fundamental to most applications. Readers should have at this point a good idea of how rapid development can be with Grails. ![]()
Rate this article
Read more | 0 comments ![]()
Posted by Bill Turner
at 12:00 AM
![]() Link directly to this article.
![]() ![]() Sunday, 28 June 2009
![]() Book - Grails 1.1 Web Application Development - Part 3
![]() Part 1 of this series can be seen here.
Part 2 of this series can be seen here. Preface and Chapter 2 - Managing Users with Scaffolding Most developers realize early in their career that there are many ways to write an application that are essentially valid. Differing levels of knowledge of practices or of available tools and frameworks lead to different decisions. Likewise, greater knowledge of a domain likely means a more nuanced design. Then there is the ever present pressure to deliver a working application within a set of existing constraints that will force different decisions. Similarly, authors would likely make different choices in the way information is presented. Unlike Beginning Groovy and Grails and Grails In Action, Jon Dickinson chose not to present the user with a chapter on Groovy after the introductory chapter. Rather the intent seems to be "learn by example". I have to admit that I felt a bit uncomfortable with this, which I attribute to my already existing knowledge of Grails and the fear that a newbie would be lost or confused by what was left out. That said, just about all the Groovy tidbits to which the reader would be exposed in the chapter that he/she would likely not understand had some explanation. Coupling that with the knowledge that chapter four will explore Groovy in greater detail, my concerns may be unfounded. The chapter starts off with a brief explanation of scaffolding, what purposes it serves and what expectations one should have for the created artifacts. This is important knowledge to share. It reinforces the idea that Grails provides a means for rapid exploration of the problem domain. After explaining that scaffolding is generated from the domain definitions the developer creates, he goes on to explain just scaffolding does in terms of providing actions and views. We are then walked through the creation of our first domains, a User domain and a Role domain. Here Jon makes a statement I feel a bit misleading, "Domain classes constitute the domain model for the application. They are mapped directly to database tables by the Grails framework...". [emphasis mine] This is not exactly true, but is probably true enough for the novice. However, I believe the beginning Grails developer should be aware that there are circumstances where domains are not one-for-one equivalent to database tables, nor are attributes necessarily one-for-one. Perhaps this will be addressed in the later chapter on GORM. Jon also provides the excellent advice to of placing your Grails classes in a package. Grails by default creates all classes in the default package. After the two domains are created, Jon leads us through creating controllers to enable scaffolding. He shows us how to create a controller through the grails command line command create-controller. We do this for both the User and the Role and we learn that both a controller class and a unit test class are created (unit tests were likewise created when the domains were created). A deeper discussion might have been warranted here to discuss the differences between create-controller and generate-controller. I can only surmise that his reasons for choosing the former to retain flexibility, to have a minimal implementation of controller logic for as long as possible while one prototypes the domain. I personally do the latter because I often find a need to start changing behavior early on. Being that the domain model is likely the most difficult aspect of the type of development for which Grails is targeted, his approach may be wiser. It is something I will integrate into my personal practice when I build my next Grails application. The next section walks through constraint definition. Constraints, we are instructed that constraints, defined in the domain classes, serve three purposes: to perform basic validations of the data, to control the ordering in which the fields are displayed in our views, and to determine which input types are used when forms are rendered. The last is true precisely because we have yet to define any views and are just using the default views provided by the scaffolding. Jon provides us with a table of constraints that are available to the developer. Developers should have been cautioned, in my opinion, that some of the constraint definitions have an impact on table definitions, while others do not. After defining constraints, the chapter turned to creating relationships between tables. Since there are only two domains present in the application thus far, he only demonstrates the creation of a one-to-many relationship between Role and User. The reader is somewhat mislead here by the suggestion that he must add several pieces of code to the Role class when only the statement static hasMany = [users:User] is necessary. I presume a competent developer would likely understand that neither the addition of the constraint, nor the addition of the toString method is necessary to the relationship definition. The toString method definition, by the way, has the unnecessary access modifier public specified. The default visibility of Groovy methods is public. The final section is about using the BootStrap class to load data into the database at startup. At this point in the book project, we are still using the pre-configured HSQLDB, an in memory database. Personally, I feel it is a best practice to avoid creating a physical database as long as possible. Thus, this is a practice I use extensively. Of course, if your project involves legacy tables, you will not have such luxury. This is a chapter full of red meat for the aspiring Grails developer. Though we have only just begun, much has been learned about application development using Grails. ![]()
Rate this article
Read more | 0 comments ![]()
Posted by Bill Turner
at 12:00 AM
![]() Link directly to this article.
![]() ![]() |
Latest Posts
19-Jun-2010
» Adding Feeds With Grails Plugins 26-Apr-2010 » April 2010 Groovy - Grails Job Market 13-Apr-2010 » GR8 in the US is Friday ![]() Archives
![]() Categories
![]() Bookmarks
![]() Authors
![]() Search
Syndicate This Site
|
|||||||||||||||||||||||||||||||||||||||||||||||||||