• No results found

Creating the Recipes interface using Scaffolding

In document Rails Cookbook (Page 36-39)

Rails uses generators to help you do some common tasks. We’ll use a generator to create a scaffold.

Scaffolding is the much talked about but poorly understood feature of Rails. It’s meant to be a starting point… to give you a quick interface where you can do some simple testing and get some of the mundane repetitive code written for you. How-ever, scaffolding can only take you so far and is not meant for use in production, hence the name “scaffolding”. There are some steps you'll need to take to clean up the scaffolding.

The Scaffold Generator

Let's create a simple interface that will allow us to manage recipes in the system. The scaffold generator creates a mod-el, controller, a set of views, and a migration, or a table definition. At the command prompt, move into your cookbook project folder

cd cookbook

The generate scaffold command takes several parameters. The first parameter is the model name. Model names are sin-gular. The generator will use this model name to create a controller and a definition for a database table. Both of these, by convention, will be pluralized. The second parameter is a string that defines your database table structure. Each field can be specified along with its data type. The scaffold generator uses this information to build the web forms your users will see. They won't be pretty but they will work.

Type (all on one line)

rails generate scaffold recipe title:string ingredients:text instructions:text The generator runs, creating the following output:

invoke active_record

create db/migrate/20100903192809_create_recipes.rb create app/models/recipe.rb

invoke test_unit

create test/unit/recipe_test.rb create test/fixtures/recipes.yml route resources :recipes

invoke scaffold_controller

create app/controllers/recipes_controller.rb invoke erb

create app/views/recipes

create app/views/recipes/index.html.erb create app/views/recipes/edit.html.erb create app/views/recipes/show.html.erb create app/views/recipes/new.html.erb create app/views/recipes/_form.html.erb invoke test_unit

create test/functional/recipes_controller_test.rb invoke helper

create app/helpers/recipes_helper.rb invoke test_unit

create test/unit/helpers/recipes_helper_test.rb invoke stylesheets

create public/stylesheets/scaffold.css

The generator created a recipe model which we'll use to work with the database. It also created a controller called recipes_controller.rb. The controller will contain all of the logic that handles user requests and interacts with the models. In fact, if we look in there, it’s already written it for us! It’s got code to handle creating, editing, listing, viewing, and deleting of recipes. Because these are all common tasks, the generators can do a pretty solid job of handling this for us.

The model we just created requires a database table called “recipes”. Normally, you’d go and create that database table using some sort of SQL statement or visual tool. In Rails, we use migrations. But before we can talk about that, we need to talk about how Rails works with databases.

Figure 4.1. The Recipes table

The Recipe model maps to a 'recipes' table and assumes the table has a primary key called ID.

Scaffolding Issues

Scaffolding is not dynamic. Now that we’ve generated these, we can’t rely on scaffolding any more. Any manu-al changes we make would be destroyed if we attempted to run the scaffold generator again. That means that if we change the table, we’ll need to modify the views. That’s okay though because we already have a good starting point.

Databases and Rails

Open the file config/database.yml and review the contents of the file. It should look something like this:

Example 4.1. code/03_recipes/cookbook/config/database.yml

# SQLite version 3.x

# gem install sqlite3-ruby (not necessary on OS X Leopard) development:

adapter: sqlite3

database: db/development.sqlite3 pool: 5

timeout: 5000

# Warning: The database defined as "test" will be erased and

# re-generated from your development database when you run "rake".

# Do not set this db to the same as development or production.

test:

This is a YAML file. (rhymes with camel) It’s a structured configuration format that maps directly to nested hashes in Ruby and is very common for configurations in Ruby on Rails. Tabs must not be used in YAML files. Instead, two spaces are used for each indentation.

Set Your Spaces

Now would be a good time to ensure that the text editor you're using has soft-tabs instead of regular tabs.

To ensure that your Ruby code fits in with that of other developers, you want to set your tabs to 2 spaces.

• Adapter is the database adapter that we want to use. Examples are mysql, sql_server, oracle, postgresql, and sqlite3. We’re using sqlite3 because it’s easy for beginners, requires no setup, and is the default database for a new Rails project.1.

• Database is the name of the database. In this case, it’s the path to the database file. Other complex adapters would have you specify the database name or Oracle TNSNames entry here, and then you would have host, username, and password fields as well.

Configuring the Database

With SQLite3, the database does not need to exist before we start the project; it will be created for you when you run your first migration (but don’t worry about that just yet!) Other databases like MySQL or Microsoft SQL Server require that the database (or schema) exist and that the appropriate privileges are applied. Since we’re trying to get you excited about Rails, we want to keep the momentum going. Using SQLite3 as a database makes it really simple to create a work-ing rapid prototype. You can then move to a different database later, because you’ll define your database tables uswork-ing pure Ruby code instead of database-specific SQL DDL statements.

Migrations

Migrations are used to modify your database. You use them to execute DDL statements against your database system.

One of the best things about them is that they allow you to define your database as it changes; you can roll your changes back if they don’t work without worrying about goofing up your database.

They’re also an invaluable tool when moving to production. Migrations are supported by all of the Rails database adapters. This means that you can change database systems and apply the migration to the new database which will

cre-ate your structures for you. This elimincre-ates the need to know the various dialects of data definition languages that may change across database systems. Developers can test with SQLite3, develop with MySQL, and deploy to Oracle.

The migration file

Open the file db/migrate/XXXXXXXX_create_recipes.rb. The XXXXXXX part will be a numerical times-tamp for the moment in time the file was created. This timestimes-tamp will help the Rails Migration system determine if it's been applied, and it also allows multiple developers to modify an application's schema without creating bottlenecks. It’s contents should resemble this:

Rails uses the information in this file to create a ‘recipes’ table in the database. Note that the above definition does not include a primary key field. Unless you specify otherwise, Rails will create an "id" column automatically, and will mark it as a primary key.

Why is the table name “recipes” and not “recipe”? Remember that by default, Rails likes table names to be the plural form of your model. It’s pretty smart too because it can do things like person => people and category => categoies. This isn’t mandatory but if we follow these conventions, we can save a few lines of code and skip a few steps. Rails will auto-matically look for the recipes table when we access the Recipe model in our code.

Creating the table from the migration

At this point, the table doesn't ctually exist in our database - we just have the “blueprint” for it in Ruby code. To execute the migration, we'll run the command

rake db:migrate

from our command line. Run that command and you’ll see feedback stating that our recipes table was created.

== CreateRecipes: migrating ==================================================

-- create_table(:recipes) -> 0.0020s

== CreateRecipes: migrated (0.0022s) =========================================

In document Rails Cookbook (Page 36-39)

Related documents