Build a blog with Grails - tutorial number 2

In the last tutorial we got our project up and running using Netbeans 6.5 and MySql. We modified the default settings to allow our app to communicate with MySql using the correct drivers and then modified the default layout so that we can build on our own look and feel.

In this tutorial we are going to create the primary controller for our application. After that's done, we'll map a URL to our new controller that will handle requests to the root of our app. We'll also make sure we have a view to display something to our app's user. Lastly, we're going to create some domain classes and configure Netbeans to allow us to visually get a handle on our database.

A bit of a disclaimer here: Everything that I'm doing is subject to change as the app progresses. Since I haven't sat down and designed the app beforehand, I'm just building this app day-by-day. There will probably be other ways to do things, perhaps even better ways to do things. You are more than welcome to stray from the path and do things the way you see fit. As a matter of fact I encourage it.

Off we go.
At the end of tutorial 1 I left it to you to do the css styling for the layout and view we used in our app. I did mine on my end here, and I admit I made a couple changes. You're more than welcome to go with mine or use your's. Here's how mine ended up - It's a prime example of why programmers don't do UI. Oh well, I wear my inability to create visually appealing web sites as a badge of honor.



It's pretty basic, but we have to start somewhere, right?

Let's take control.

For our first task today, we're going to create a controller. It will be the primary one for our app. Creating a controller is simple. Right click on Controllers, then select "New -> Grails Controller."



When the dialog comes up we'll name our controller "Site." Grails will automatically tack on "Controller" and you'll end up with a new Groovy class created under "Controllers" by the name of "SiteController.groovy."


Our new controller will already have a default closure of "index" when Grails creates it. These closures are going to be known as "actions":

class SiteController {

    def index = { }

}

We're going to go ahead and keep this as is. No need to change anything in our controller at this time. However, we are going to make a few changes to things:

First, we're going to move that "index.gsp" file from it's current location. When Grails creates a controller, it also creates a folder under "Views and Layouts" named after the controller ( but less the "Controller" part of the name. The closures you define in your controller will map directly to views in the appropriate folder by the same name. You can always tell your actions which display to show to the user, but without your intervention a view with the same name as your action will be the one served up in the browser. So, our index action will display site/index.gsp when the index action is requested under our Site controller.

Let's look at that a different way. What would happen if the following URL was requested?

http://localhost:8080/GroovyBlog/site/index

The above URL would cause our index action in our SiteController class to be called. After logic in the action was handled, Grails would then attempt to display a file named "site/index.gsp." However, we don't have a file of that name under the site folder. Luckily we do have a file named index.gsp so we don't have to create it.

Let's move that index.gsp file from the root of our site into the folder named "site" under "Views and Layouts." In Netbeans you can just drag the file and it will be moved. If you want to do it another way you're more than welcome to do so.

If you were to run the app, you would most likely get a 404 result. There's no file named index.gsp in our root anymore. Here's why our app is looking for that view, open up the file called UrlMappings.groovy under "Configuration."

class UrlMappings {
    static mappings = {
      "/$controller/$action?/$id?"{
	      constraints {
			 // apply constraints here
		  }
	  }
      "/"(view:"/index")
	  "500"(view:'/error')
	}
}
As you can see, requests to the root of our application ( "/" this, of course, is the same as http://localhost:8080/GroovyBlog/ ) has been configured to be answered by a view ( a GSP ) named "index." We're going to change that to the following:

class UrlMappings {
    static mappings = {
      "/$controller/$action?/$id?"{
	      constraints {
			 // apply constraints here
		  }
	  }
      "/"(controller:"site",action:"index")
	  "500"(view:'/error')
	}
}
We've modified our UrlMappings.groovy class so that requests to the root of our app will be answered by the index action in our SiteController. Now that an index.gsp file exists in the folder called "site" we won't get a 404 error, we should see the same thing we saw previously when we ran our app.

We could have just specified "/"(controller:"site"). That would have been the same as what we did. By default if only the controller is named it will call the index action. However, I just took the path of completeness and specified which controller and action.

Let's do it.



As you can see, Grails' UrlMapping.groovy is pretty cool. We'll be using a lot more of that in tutorials to come. However, it's time to move on. Our app is pretty lame at this point. While we can pat ourselves on the back by virtue of the fact that we've done a few cool-ish things, our app ain't nothing without some data.

Data! Data! Data!

Grails uses an Object Relational Mapping implementation called GORM. Beyond that it uses Hibernate. The Domain Classes you build in your Grails app determines the data that comprises your app. Let's identify what kind of data we should have for our blog app.

At our most basic level we'll have a domain class by the name of Blog. Our Blog will most likely have a User, but it could also probably have many Users. For sure our Blog will have at least one Post, but hopefully many Posts. It is probably a good idea to ensure that those Posts can be associated with the individual Users who created them. Posts can have many Categories, Tags and Keywords. Let's go ahead and create those.

Just like when you created the SiteController, create those domain classes. Right click on "Domain Classes" and then "New -> Grails Domain Class."



Initially, you're going to have a pretty basic class created:

class Blog {

    static constraints = {
    }

}
So here's our Blog class as it is created. All that Grails has given us is a closure named constraints. We'll talk more about constraints in another tutorial. Today, we're concerned about our Domain Classes and their associations. As I pointed out earlier our Blog can have many Users as well as many Posts. Here's how we'll define those relationships:

class Blog {

    String url
    String name

    static hasMany = [users:User, posts:Post]

    static constraints = {
    }
}
Our Blog "hasMany" posts by virute of the fact that a variable named "posts" is associated with the "Post" class and "users" is associated with the "User" class. I've also identified two other variables: the url and the name of the Blog which have been typed as Strings.

Here's our Post class:

class Post {

    String title
    String body
    String extendedBody
    String slug
    User author
    int views

    static belongsTo = [User,Blog]
    String status

    boolean acceptTrackbacks
    boolean acceptComments

    static hasMany = [tags:Tag, keywords:Keyword, subjects:Subject]

    Date publishDate
    Date dateCreated
    Date lastUpdated

    static constraints = {
    }
}
Notice that in our Post class we have told GORM that a Post has a many-to-many relationship with not only a Blog, but also a User. Additionally, a Post is also identified with a specific User through authorship. This will be necessary later on. Also a Post will have a many-to-many relationship with Tags, Keywords and Subjects.

I also identified a few other variables that I believe will be associated with a blog post. However, I want to talk very briefly about two of those in particular: dateCreated and lastUpdated. Using those variables, named as they are with the type of Date, the values associated with those variables will be handled automatically by GORM. When a post is created, we will not have to supply that value to be stored in the database. GORM will take care of it for us. The same can be said for lastUpdated. When a post is updated in the database, the value will be handled automatically for us.

Each of our domain classes will be uniquely identified by virtue of an id, but we don't have to define it. GORM will take care of that.

We're not using the word "Category" because Groovy uses a class by the name of Category and since we are not using packages if we made our own class named Category, we would have problems. I found this out through experience. After a couple of hours of searching I found this. Instead, we'll use "Subject." Like I said, if we were to put our domain classes into packages this wouldn't be an issue. For the sake of simplicity, I'm not using packages but you are free to do this on your own if you prefer.

I'm not walking through each one, but all the Domain files will be available at the end of the tutorial. I want to point something out real quick here before I wrap things up. Netbeans integrates well with MySQL. If you click on the "Services" tab on the left pane of the IDE you'll see this:



If you click on Databases and expand it like so, you should see this:



We're going to create a connection to our MySql Database so we can see the tables created when we start our app. You may already have your own MySql administration tool that you prefer to use whether it be PhpMyAdmin, MySql Administrator or perhaps you prefer using the console. While I don't mind the console, I like to have a nice GUI tool to use from time to time. I also like to have very few windows open. So the IDE integration is nice to have.

Highlight the "MySQL (Connector/J driver)" and right click. Then click on "Connect Using." Fill in the dialog that opens with the appropriate values. You could also fill in these values by checking the box at the bottom that reads, "Show JDBC URL." A text box will be displayed and you can paste the URL we specified in our DataSource.groovy file. You'll still have to fill in the "User Name" and "Password" however.



Provided you have all your domain classes created and Grails configured to "create" or "create-drop" when your app starts ( we're using create-drop ) all the necessary tables will be created. Now you can get a visual of all the tables that GORM creates based on how you've told it to do it through your domain classes.

If you've configured your connection successfully you should see something like this:


Of course we don't have any tables to see because we haven't created all our models and restarted the app. However, we will tomorrow.

So let's wrap things up.

Today we created a controller and told Grails that requests to the root of our application should be handled by the index action of our new controller. The index view that we modified in tutorial 1 was moved so that the index action of our new controller would have a view that would be served to the user.

Then we created some domain classes that will represent the data for our app. While it may not be 100 percent complete, it's a good start. Next time, since we learned how to connect to our database via Netbeans, we'll be able to see all the tables that are created based on the domain models for our app. Then we'll use our domain classes and load some data via BootStrap so that we can start making this app do something.

Unitl then I've put the GSPs, .css and domain classes into a .zip file. If you want them for reference or to use in your app, you're more than welcome to them. You can get them at this link. Additionally, it would be a good idea for you to bookmark the following link to some handy-dandy Grails documentation that we'll be using in the next tutorial.

As usual, you're more than welcome to leave comments, suggestions or an abundance of praise.

Next up, Tutorial #3.
OpenID accepted here Learn more about OpenID

About this Entry

This page contains a single entry by Jim published on April 6, 2009 8:15 PM.

Because the Internet needs another "build a blog with ..." tutorial was the previous entry in this blog.

Build a blog with Grails - tutorial number 3 is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.