toy_app ROR 小例子
1. 前期准备
创建工程:
$ cd ~/rails_projects
$ rails _5.0.0.1_ new toy_app
$ cd toy_app
修改 gemfile 文件,增加 Heroku 生产环境需要的 gem 外,在其中加入:
group :production do
gem 'pg', '0.18.4'
end
pg 用来连接 PostgreSQL 数据库,Heroku 使用这个数据库。避免在生产环境安装 sqlite3 ,这是因为 Heroku 不支持 SQLite ,做如下修改。
group :development, :test do
gem 'sqlite3', '1.3.11'
gem 'byebug', '9.0.0', platform: :mri
end
然后使用 bundle install 命令安装并包含这些 gem:
$ bundle install --without production
--without production 指明不安装生产环境使用的 gem。
最后把演示程序纳入版本控制:
$ git init
$ git add -A
$ git commit -m "Initialize repository"
创建仓库,推送代码:
$ git remote add origin [email protected]:/demo_app.git
$ git push -u origin master
在 Application 控制器中添加 hello 动作
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
def hello
render html: "hello, world!"
end
end
设置根路由,把根路由指向 Application 控制器中的 hello 动作。
config/routes.rb
Rails.application.routes.draw do
root 'application#hello'
end
提交改动后,推送到 Heroku 中:
$ git commit -am "Add hello"
$ heroku create
$ git push heroku master
2. Users 资源
有多少不同的注册表单,就有多少定义用户 数据模型 的方式。“ 资源 ”的意思是把用户设想为对象,可以通过 HTTP 协议在网页中增删改读。
把 scaffold 传给 rails generate 命令就可以使用 Rails
的脚手架了。传给 scaffold 的参数是资源名的单数形式(这里是 User ),后面可以再跟着一些可选参数,指定数据模型中的字段:
$ rails generate scaffold User name:string email:string
这样就可以实现了 Users 模型。注意,没必要指定 id 字段,Rails 会自动创建并将其设为表的 主键 。
接下来我们要用 rails db:migrate 命令迁移(migrate
)数据库:
$ rails db:migrate
运行本地 Web 服务器:
$ rails server -b $IP -p $PORT # 在本地要执行 `rails server`
之后可以访问 /users
,/users/1
,/users/new
,/users/1/edit
等页面。
MVC视图
Users
资源中相关的 URL
映射到控制器动作,把根路由指向 Users
控制器的动作。
config/routes.rb
Rails.application.routes.draw do
resources :users
root 'users#index'
end
一个控制器中有多个动作,脚手架会自动生成一些动作。
这个应用中简化的 index 动作 @users = User.all
,让 User 模型从数据库中取出所有用户,然后把结果赋值给 @users 变量:
app/controllers/users_controller.rb
class UsersController < ApplicationController
.
.
.
def index
@users = User.all
end
.
.
.
end
具体而言,调用 Rails
中的 Active Record 库后, User.all
就能获取数据库中的所有用户:
app/models/user.rb
class User < ActiveRecord::Base
end
定义 @users
变量后,控制器再调用视图。以 @
开头的变量是 实例变量 ,在视图中自动可用。这里, index.html.erb 视图中的代码遍历 @users
,为每个用户生成一行 HTML :
app/views/users/index.html.erb
Listing users
Name
Email
<% @users.each do |user| %>
<%= user.name %>
<%= user.email %>
<%= link_to 'Show', user %>
<%= link_to 'Edit', edit_user_path(user) %>
<%= link_to 'Destroy', user, method: :delete,
data: { confirm: 'Are you sure?' } %>
<% end %>
<%= link_to 'New User', new_user_path %>
3. Microposts 资源
生成 Microposts
资源的代码:
$ rails generate scaffold Micropost content:text user_id:integer
执行迁移,更新数据库,使用新建的数据模型:
$ rails db:migrate
把微博相关的 URL 映射到 Microposts 控制器上:
config/routes.rb
Rails.application.routes.draw do
resources :microposts
resources :users
root 'users#index'
end
限制微博的长度最多为 140 个字符:
app/models/micropost.rb
class Micropost < ApplicationRecord
validates :content, length: { maximum: 140 }
end
Rails 最强大的功能之一,是可以在不同的 数据模型 之间建立 关联 。
一个用户拥有多篇微博,还添加了存在性 验证 ,确保用户名、邮箱的内容不能为空:
app/models/user.rb
class User < ApplicationRecord
has_many :microposts
validates: name, presence: true
validates: email, presence: true
end
一篇微博属于一个用户,还添加了存在性验证,确保微博的内容不能为空:
app/models/micropost.rb
class Micropost < ApplicationRecord
belongs_to :user
validates :content, length: { maximum: 140 }, presence: true
end
User
和 Micropost
都继承自 ApplicationRecord 类,而这个类继承自 ActiveRecord::Base 类,这是 Active Record
为模型提供的基类。继承 ActiveRecord::Base
类,模型对象才能与数据库通讯,才能把数据库中的列看做 Ruby 中的属性。Rails 应用中的所有控制器都继承 ApplicationController 。
部署这个应用
$ git push heroku
还要执行下面的命令迁移生产环境的数据库,这样应用才能使用数据库:
$ heroku run rails db:migrate