文章目录
  1. 1. 课程目标
  2. 2. 课程复盘
    1. 2.1. 1. 建立一个新 Rails 项目,并建立 git 做版本控制
    2. 2.2. 2. 帮 Rails 项目穿上衣服“Bootstrap”
    3. 2.3. 3. 套用 Bootstrap 的 html 样式
    4. 2.4. 4. 制作漂亮的“提示信息” (以下内容无需记忆)
    5. 2.5. 5. 经典四部曲:model-controller-action-view-routes
    6. 2.6. 6. 输入框与栅格系统
    7. 2.7. 7. Group CRUD
    8. 2.8. 8. 在 Group model 加入“标题限制”
    9. 2.9. 9. 错误提示消息
    10. 2.10. 10. 共用“表单”
    11. 2.11. 11. 将表单换为 Bootstrap 提供的版型,使用 SimpleForm 简化
    12. 2.12. 12. 符号的用法

课程目标

接下来会以一个“讨论版”为主题,实际让同学了解如何“从零打造”手写出一个网站。

这个讨论版会有:

  • 使用者注册以及登录功能
  • 开新讨论区、留言功能
  • 加入讨论区、退出讨论区功能
  • 权限管理功能
  • 热门文章排序功能
  • 了解什么是 RESTful

当你把这次应用程序实作完成,并上线后,你会学会:

  • 怎么把需求变成会动的 Rails 应用程序
  • 如何在 Rails 套版
  • 如何制作使用者登录功能
  • 重要 Rails 观念以及 API
    • CRUD
    • RESTful
    • member, collection
    • helper
    • partial
    • scope
  • 找到 Rails 第三方 gem 的技巧
  • 要怎么把你的应用程序放到网络上

这几乎是一个 Rails 新手应该学的一切了,有了这些基础技巧之后,你再学更难的技巧,或者是要自己做出复杂的东西,就不会那么容易失败了。

课程复盘

1. 建立一个新 Rails 项目,并建立 git 做版本控制

1
2
3
4
5
rails new rails101
cd rails101
git init
git add .
git commit -m "Initial Commit"

2. 帮 Rails 项目穿上衣服“Bootstrap”

1
2
3
4
5
6
7
8
9
10
gem 'bootstrap-sass' #Gemfile
bundle install #每次修改完 Gemfile 都记得要command + s 保存 ,然后执行 bundle install
mv app/assets/stylesheets/application.css app/assets/stylesheets/application.scss
@import "bootstrap-sprockets";
@import "bootstrap";
git add .
git commit -m "add bootstrap to project"

3. 套用 Bootstrap 的 html 样式

(1)新增 navbar

1
2
mkdir app/views/common
touch app/views/common/_navbar.html.erb

填入

app/views/common/_navbar.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<nav class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/">Rails 101</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav navbar-right">
<li>
<%= link_to("登录", '#') %>
</li>
</ul>
</div>
</div>
</nav>
<!-- 以上部分,不需要记忆 -->

PS:

class
1
2
3
4
5
6
7
8
9
10
11
前者是 100% 宽度布局,后者是 固定宽度 布局。
```<div class="collapse navbar-collapse">```中 collapse的用法:
这是Bootstrap 折叠(Collapse)插件,为了给导航栏添加响应式特性,要折叠的内容必须包裹在带有 class .collapse、.navbar-collapse 的 <nav> 中。
参考:[Collapse](http://v3.bootcss.com/javascript/#collapse)。
对应导航栏务必使用 <nav> 元素,或者,如果使用的是通用的 <div> 元素的话,务必为导航条设置 role="navigation" 属性,这样能够让使用辅助设备的用户明确知道这是一个导航区域。
(2)新增 footer
新增 footer

touch app/views/common/_footer.html.erb

1
2
3
4
5
6
7
8
9
10
11
填入
```ruby app/views/common/_footer.html.erb
<footer class="container" style="margin-top: 100px;">
<p class="text-center">Copyright ©2017 Rails101
<br>Design by
<a href="http://courses.growthschool.com/courses/rails-101/" target=_new>xdite</a>
</p>
</footer>
<!-- 以上部分,不需要记忆 -->

以上部分,不需要记忆

(3)修改全域 HTML 样式 application.html.erb

app/views/layouts/application.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html>
<head>
<title>Rails101</title>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
<body>
<div class="container-fluid">
<%= render "common/navbar" %>
<%= yield %>
</div>
<%= render "common/footer" %>
</body>
</html>

PS:上述代码部分,如下命令的用途:

<%= csrf_meta_tags %>

<%= stylesheet_link_tag ‘application’, media: ‘all’, ‘data-turbolinks-track’: ‘reload’ %>

<%= javascript_include_tag ‘application’, ‘data-turbolinks-track’: ‘reload’ %>

(4)产生一个新的空 Hello World 页面

1
2
rails g controller welcome
touch app/views/welcome/index.html.erb

填入

app/views/welcome/index.html.erb
1
<h1> Hello World! </h1>

修改 config/routes.rb,改成以下内容

config/routes.rb
1
2
3
Rails.application.routes.draw do
root 'welcome#index'
end

(5) git 进度存档

1
2
git add .
git commit -m "add bootstrap html"

4. 制作漂亮的“提示信息” (以下内容无需记忆)

(1)在 require_tree 上加入 //= require bootstrap/alert

app/assets/javascripts/application.js
1
2
3
4
5
6
... (一堆注解)
//= require jquery
//= require jquery_ujs
//= require turbolinks
+//= require bootstrap/alert
//= require_tree .

(2)新增 app/views/common/_flashes.html.erb

1
touch app/views/common/_flashes.html.erb

填入

app/views/common/_flashes.html.erb
1
2
3
4
5
6
7
8
<% if flash.any? %>
<% user_facing_flashes.each do |key, value| %>
<div class="alert alert-dismissable alert-<%= flash_class(key) %>">
<button class="close" data-dismiss="alert">×</button>
<%= value %>
</div>
<% end %>
<% end %>

这里的user_facing_flashes和flash_class(key) 会在相应的flashes.helper.rb中定义。

(3)加入 app/helpers/flashes_helper.rb

1
touch app/helpers/flashes_helper.rb

加入以下内容:

app/helpers/flashes_helper.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
module FlashesHelper
# 定义常量
FLASH_CLASSES = { alert: "danger", notice: "success", warning: "warning"}.freeze
def flash_class(key)
FLASH_CLASSES.fetch key.to_sym, key
end
def user_facing_flashes
flash.to_hash.slice "alert", "notice", "warning"
end
end

上述代码每一行具体是什么意思?

PS:

这里的.freeze和.fetch以及flash.to_hash.slice “alert”, “notice”, “warning” 的用法:

(4)在 application.html.erb 内加入 flash 这个 partial

在 <%= yield %> 前加入 <%= render “common/flashes” %>

app/views/layouts/application.html.erb
1
2
<%= render "common/flashes" %>
<%= yield %>

(5)git 存档

1
2
git add .
git commit -m "add bootstrap flash function"

5. 经典四部曲:model-controller-action-view-routes

以建立讨论群的架构为例。

(1)建立model和相应的数据库

1
2
rails g model group title:string description:text
rake db:migrate

提示:model的名称一般为单数(group),每次产生 migration 之后都要运行 rake db:migrate,然后生成的数据表名称一般为复数。

(2)产生 groups controller

1
rails g controller groups

提示:controller的名称一般为复数(groups)

(3)建立 index action

app/controllers/groups_controller.rb
1
2
3
4
5
class GroupsController < ApplicationController
def index
@groups = Group.all
end
end

(4)建立 index 的 view

app/views/groups/index.html.erb```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
加入如下内容:
```ruby app/views/groups/index.html.erb
<div class="col-md-12">
<div class="group">
<%= link_to("New group", new_group_path, class: "btn btn-primary pull-right") %>
</div>
<table class="table table-hover">
<thead>
<tr>
<td>#</td>
<td>Title</td>
<td>Description</td>
</tr>
</thead>
<tbody>
<% @groups.each do |group| %>
<tr>
<td>#</td>
<td><%= link_to(group.title, group_path(group)) %></td>
<td><%= group.description %></td>
<td>
<%= link_to("Edit", edit_group_path(group), class: "btn btn-sm btn-default")%>
<%= link_to("Delete", group_path(group), class: "btn btn-sm btn-default",
method: :delete, data: { confirm: "Are you sure?" } )%>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>

这里的

1
<% @groups.each do |group| %>

中@groups也可以看出从@groups数据表名称为复数。

(5)在 routing 上挂上 groups

config/routes.rb
1
2
3
4
Rails.application.routes.draw do
+ resources :groups
root 'welcome#index'
end

这个网站讲解Bootstrap更为透彻:http://www.runoob.com/

6. 输入框与栅格系统

app/views/groups/new.html.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div class="col-md-4 col-md-offset-4">
<h2>新增讨论版</h2>
<hr>
<%= form_for @group do |f| %>
标题
<%= f.text_field :title %>
<br>
叙述
<br>
<%= f.text_area :description %>
<br>
<%= f.submit "Submit", :disable_with => 'Submitting...' %>
<% end %>
</div>

上述代码中,col-md-4和col-md-offset-4是Bootstrap响应式格栅系统。col-md-offset-*是 列偏移。

使用 .col-md-offset- 类可以将列向右侧偏移。这些类实际是通过使用 选择器为当前元素增加了左侧的边距(margin)。例如,.col-md-offset-4 类将 .col-md-4 元素向右侧偏移了4个列(column)的宽度。

示例:

1
2
3
4
5
6
7
8
9
10
11
<div class="row">
<div class="col-md-4">.col-md-4</div>
<div class="col-md-4 col-md-offset-4">.col-md-4 .col-md-offset-4</div>
</div>
<div class="row">
<div class="col-md-3 col-md-offset-3">.col-md-3 .col-md-offset-3</div>
<div class="col-md-3 col-md-offset-3">.col-md-3 .col-md-offset-3</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3">.col-md-6 .col-md-offset-3</div>
</div>

7. Group CRUD

groups_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class GroupsController < ApplicationController
def index
@groups = Group.all
end
def new
@group = Group.new
end
def show
@group = Group.find(params[:id])
end
def edit
@group = Group.find(params[:id])
end
def create
@group = Group.new(group_params)
if @group.save
redirect_to groups_path
else
render :new
end
end
def update
@group = Group.find(params[:id])
if @group.update(group_params)
redirect_to groups_path, notice: 'Update Success'
else
render :edit
end
end
def destroy
@group = Group.find(params[:id])
@group.destroy
redirect_to groups_path, alert: 'Group deleted'
end
private
def group_params
params.require(:group).permit(:title, :description)
end
end

8. 在 Group model 加入“标题限制”

app/models/group.rb
1
2
3
class Group < ApplicationRecord
validates :title, presence: true
end

9. 错误提示消息

app/views/groups/edit.html.erb
1
2
3
4
5
6
7
<% if @group.errors.any? %>
<ul>
<% @group.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<% end %>

10. 共用“表单”

app/views/groups/edit.html.erb
1
2
3
4
5
6
<div class="col-md-4 col-md-offset-4">
<h2>编辑讨论版</h2>
<hr>
<%= render "form" %>
</div>

11. 将表单换为 Bootstrap 提供的版型,使用 SimpleForm 简化

打开 Gemfile,然后新增一行 gem ‘simple_form’

Gemfile
1
2
gem 'bootstrap-sass'
+ gem 'simple_form'

然后执行

1
bundle install

安装 gem。

安装 simple_form for bootstrap 的设定

执行:

1
rails generate simple_form:install --bootstrap

这个指令会产生两个文件

  • config/initializers/simple_form.rb
  • config/initializers/simple_form_bootstrap.rb (这个是 Bootstrap 表单的“布景”)

把内容改成

app/views/groups/_form.html.erb
1
2
3
4
5
6
7
<%= simple_form_for @group do |f| %>
<div class="form-group">
<%= f.input :title, input_html: { class: "form-control"} %>
<%= f.input :description, input_html: { class: "form-control"} %>
</div>
<%= f.submit "Submit", class: "btn btn-primary", data: { disable_with: "Submiting..." } %>
<% end %>

simple_form 提供的错误信息,直接是在栏位旁边的。更明显更直观。

1
2
git add .
git commit -m "replace form with simple_form bootstrap template"

12. 符号的用法

下面2个代码效果相同

1
2
3
<%= f.label "title", :class => "string optional control-label" %>
<%= f.label "title", class: "string optional control-label" %>
# 注意冒号与双引号直接的空格,:key => value == key: value 只是语法糖而已
文章目录
  1. 1. 课程目标
  2. 2. 课程复盘
    1. 2.1. 1. 建立一个新 Rails 项目,并建立 git 做版本控制
    2. 2.2. 2. 帮 Rails 项目穿上衣服“Bootstrap”
    3. 2.3. 3. 套用 Bootstrap 的 html 样式
    4. 2.4. 4. 制作漂亮的“提示信息” (以下内容无需记忆)
    5. 2.5. 5. 经典四部曲:model-controller-action-view-routes
    6. 2.6. 6. 输入框与栅格系统
    7. 2.7. 7. Group CRUD
    8. 2.8. 8. 在 Group model 加入“标题限制”
    9. 2.9. 9. 错误提示消息
    10. 2.10. 10. 共用“表单”
    11. 2.11. 11. 将表单换为 Bootstrap 提供的版型,使用 SimpleForm 简化
    12. 2.12. 12. 符号的用法