Beyond Java - Bruce Tate [68]
mysql> CREATE TABLE trails (
-> id int(6) NOT NULL auto_increment,
-> name varchar(20),
-> description text,
-> difficulty varchar(20),
-> primary key (id));
Query OK, 0 rows affected (0.36 sec)
Notice the names. They are important. By convention, if you're working with more than one row (as in a table or a list), the name should be a plural. A column or class that refers to a singular object should be singular. Rails is smart enough to translate English plurals, so it knows to create a model called Person for a table called people. Watch the capitalization in these examples, too. It's important. If you follow Rails conventions with your names, you can just stay with Rails defaults, and your code will be much more concise.
You'll need to tell Rails where to find your database. Edit config/database.yml to look like this:
development:
adapter: mysql
database: trails
host: localhost
username: root
password: password
Stop and restart the server. (You only have to do so when you change your database configuration.) Let's generate a simple model. In the trails directory, simply type:
ruby script/generate model trail
Rails generates the model, some helper files, tests, and fixtures. For example, you can take a look at the model. Edit the file at app/models/trail.rb:
class Trail < ActiveRecord::Base
end
That certainly looks anticlimactic. It looks like you'll simply type custom code here, in hopes that Rails will generate the rest of the code somewhere else. But that's not what happens at all. At runtime, Rails will load the ActiveRecord base class. Rails will look at the name of the class and load the definition of a table called trails. Then, it will dynamically add attributes, getters, setters, and database access methods to the Trail base class! So, there's a lot more than meets the eye.
One of the scripts that Rails generates lets you manipulate your model from an irb session. Type:
ruby script/console
You can now easily manipulate your model. For example, you can say:
Trail.new do |trail|
trail.name="Walnut Creek"
trail.description="Meandering trail in Austin park"
trail.difficulty="hard"
trail.save
end
Now, you'll need a controller. You can generate that, too:
ruby script/generate controller trails
ruby script/generate model trails
You just created the model and a default controller in app/controllers/trails_controller.rb for a collective page of trails. When you edit it, the controller is empty. Make it look like this:
class TrailsController < ApplicationController
def index
render_text "This will be a trail someday..."
end
end
Point your browser to the URL http://localhost:3000/trail. You'll see your message printed. Of course, you didn't learn Rails to print strings, so change your controller to this:
class TrailsController < ApplicationController
scaffold :trails
end
scaffold is a method. The first parameter is :trails, a literal pointing to the Trails class. Save it, and load the same URL. Now, that's more interesting. You see a listing of trails. Click on the new trail link on the bottom. That's beyond interesting! You'll get a form like the one shown in Figure 7-1. You can see that the metaprogramming framework is working overtime. The scaffold method inferred the properties of the database and propagated them through the model and up to the user interface. You'll see exactly what goes into a scaffold controller later, but trust the magic for now.
Managing Relationships and Updating Views
A list of trails will not get you very far by itself. It's the interactions between objects that gets difficult. Say you want to access trails by their city. The first job is to generate the model for locations. First you'll need a database table:
mysql>