Beyond Java - Bruce Tate [69]
-> id int(6) NOT NULL auto_increment,
-> city varchar(20),
-> state varchar(20),
-> primary key (id));
Query OK, 0 rows affected (0.35 sec)
Instead of dynamically generating the scaffolding, you can simultaneously generate the source code for the controller, and view, complete with scaffolding with ruby script/generate scaffold locations. Build the model for a single location with ruby script/generate model location. While you're at it, just to get a better look at what's going on behind the curtains, do the same for Trail with ruby script/generate scaffold trails. Look at what you've done by pointing your browser to http://localhost:3000/locations. Make sure it works, and add a few locations. I'm adding Austin, Texas, and Durango, Colorado.
It's time to write some code ourselves, instead of letting Rails do all the work. You're going to need to update your trails table to point to the right row in the new locations table. You'll do so by adding a new database column that points to location_id, like this:
alter table trails add location_id int(6);
You also need to tell Rails about the relationship. Modify the Trails model and the Location model to reflect the new relationships, like this:
class Trails < ActiveRecord::Base
belongs_to :location
end
class Locations < ActiveRecord::Base
has_many :trails
end
Figure 7-1. This application has less than 10 lines of code and configuration, because Rails inferred the structure from the database
A little description here is interesting. You've created a subclass of the ActiveRecord class in the Base module. You've then fired a method called belongs_to and passed it a symbol for the Locations class. This method will fire more metaprogramming code that actually adds the properties and methods to your code that will manage the relationships for you.
Next, you're going to have to edit the Trails view and controller to edit a location. The scaffolding created the new controllers and views under trails and locations, respectively.
It's time to modify some of the view code. The view code consists of HTML, with Ruby scripting mixed in, between the <% and %> tags. First, you'll need to make sure the view has all the information it needs. You'll do this in the edit method, in the controller. Change the edit method in trails_controller.rb to create a property called @locations that has all the locations:
class TrailsController < ApplicationController
...
def edit
@trail = Trail.find(@params[:id])
@locations = Location.find_all
end
...
end
It's also time to take over the full view that lets you edit a trail. You'll want the user to pick a location from a pick list with all possible locations. Change app/views/trails/edit.rhtml to look like this:
Edit Trail
Show
As with most applications, your scaffolding won't hold up infinitely. Often you'll want to replace most of the view code. Rails lets you build toward the goal, instead of creating all of a model, view, and controller right off the bat.
Notice the code in bold. It adds an option value for all the locations (which you specified in the edit method of the controller), and selects the one that matches the one that reflects the model, shown in the variable trails.location.city.
Finally, you'll need to show the new data in the trail