本章介绍了如何迭代地创建并优化一个用来维护商品信息(包括:创建新商品、编辑现有商品、删除不再需要的商品等功能)的小型应用程序。
6.1 创建“商品维护”的应用程序
第1步:创建一个新的Rails应用程序
在指定目录(如:work目录)下,创建一个新的Rails应用程序,并将其命名为“depot”,命令如下:
work> rails new
depot
第2步:创建数据库
实际上,SQLite3是Rails默认的数据库,在创建好Rails应用程序后,也就自动创建好了一个SQLite3数据库。所以,如果不打算使用其他类型的数据库,就可以跳过这一步。
第3步:生成脚手架
要实现创建、展示、编辑、删除商品等功能,就需要创建一个数据库表和Rails模型,应用程序将通过这个模型,来使用这个数据库表和一系列创建用户界面的视图以及协调应用程序的控制器。
在Rails中,通过生成一个指定模型的脚手架(scaffold),便可以同时创建好模型、视图、控制器和迁移(在迁移文件中将自动创建数据库表)。命令如下:
depot> rails generate scaffold
Product \
title:string description:text image_url:string price:decimal
- 首先,需要切换到应用程序depot目录下来执行该命令。
- 这条命令中,Product是我们自己定义的一个模型名称,模型名称需要使用单数形式,因为要让该模型自动映射到后续生成的products表。(在Rails中,如果表名是模型名称的复数形式,那么该模型会自动映射到这张表。)
- 执行这条命令后,首先会创建一个迁移文件,文件位于:db/migrate目录中。一次迁移代表着将对数据进行一次修改,这些修改既可以更新数据库模式,也可以更新数据库中的数据。在这个迁移文件中,会自动生成一个方法,用来在数据库中创建一个名叫products的表。模型Product将自动映射到这个products表。
- 随后,会生成模型文件(位于:app/models/product.rb)、控制器文件(位于:app/controllers/product_controller.rb)和一些视图文件(位于:app/views/products目录下)。
- 命令的第2行,是在定义products这个数据库表中的每个属性的数据类型。
第4步:应用迁移
生成迁移文件后,这些迁移(或者说对数据的修改)还并没有应用到数据库中去。所以,其实目前还没有生成products这个数据库表。
应用迁移的命令如下:
depot> rake db:migrate
rake命令会去搜索所有尚未应用到数据库中的迁移,并将这些迁移应用到开发数据库中去。
第5步:启动Rails服务,访问Rails应用程序
启动Rails提供的本地服务器的命令如下:
depot> rails server
该命令会默认使用端口3000来启动本地服务器。如果访问localhost:3000,浏览器将显示RAILS的欢迎页面。如果要查看本例的商品清单页面,需要在URL中包含端口号3000和小写的控制器名products,即访问localhost:3000/products 。
第6步:进行简单的测试
使用命令:depot> rake test
可以对这个depot应用程序进行简单的测试,这是Rails根据脚手架生成的一些简单的单元、功能和集成测试。
6.2 美化商品清单
第1步:创建一些演示用的测试数据
为了在每一次进行演示时,页面展示的都是同样的测试数据,我们可以将title、description、image_url、price等测试数据写入seeds.rb文件中,它位于db目录下。
# This file should contain all the record creation needed to seed the database with its default values.
# The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup).
#
# Examples:
#
# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
# Character.create(name: 'Luke', movie: movies.first)
#---
# Excerpted from "Agile Web Development with Rails 5",
# published by The Pragmatic Bookshelf.
# Copyrights apply to this code. It may not be used to