Skip to content

Commit f17905d

Browse files
authored
Merge pull request #79 from chloerei/fix-table
修复一些因为 table 处理脚本错误删掉的内容
2 parents 206d68b + 1eb34ce commit f17905d

File tree

1 file changed

+265
-7
lines changed

1 file changed

+265
-7
lines changed

source/zh-CN/getting_started.md

Lines changed: 265 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,20 @@ class ArticlesController < ApplicationController
604604
```erb
605605
<h1>Listing articles</h1>
606606
607-
607+
<table>
608+
<tr>
609+
<th>Title</th>
610+
<th>Text</th>
611+
</tr>
612+
613+
<% @articles.each do |article| %>
614+
<tr>
615+
<td><%= article.title %></td>
616+
<td><%= article.text %></td>
617+
<td><%= link_to 'Show', article_path(article) %></td>
618+
</tr>
619+
<% end %>
620+
</table>
608621
```
609622

610623
现在访问 <http://localhost:3000/articles>,会看到已创建的所有文章的列表。
@@ -622,15 +635,15 @@ class ArticlesController < ApplicationController
622635

623636
`link_to` 方法是 Rails 内置的视图辅助方法之一,用于创建基于链接文本和地址的超链接。在这里地址指的是文章列表页面的路径。
624637

625-
接下来添加指向其他视图的链接。首先在 `app/views/articles/index.html.erb` 文件中添加“New Article”链接,把这个链接放在 <table> 标签之前:
638+
接下来添加指向其他视图的链接。首先在 `app/views/articles/index.html.erb` 文件中添加“New Article”链接,把这个链接放在 `<table>` 标签之前:
626639

627640
```erb
628641
<%= link_to 'New article', new_article_path %>
629642
```
630643

631644
点击这个链接会打开用于新建文章的表单。
632645

633-
接下来在 app/views/articles/new.html.erb 文件中添加返回 index 动作的链接,把这个链接放在表单之后:
646+
接下来在 `app/views/articles/new.html.erb` 文件中添加返回 `index` 动作的链接,把这个链接放在表单之后:
634647

635648
```erb
636649
<%= form_for :article, url: articles_path do |f| %>
@@ -640,7 +653,7 @@ class ArticlesController < ApplicationController
640653
<%= link_to 'Back', articles_path %>
641654
```
642655

643-
最后,在 app/views/articles/show.html.erb 模板中添加返回 index 动作的链接,这样用户看完一篇文章后就可以返回文章列表页面了:
656+
最后,在 `app/views/articles/show.html.erb` 模板中添加返回 `index` 动作的链接,这样用户看完一篇文章后就可以返回文章列表页面了:
644657

645658
```erb
646659
<p>
@@ -656,9 +669,236 @@ class ArticlesController < ApplicationController
656669
<%= link_to 'Back', articles_path %>
657670
```
658671

659-
TIP: 链接到当前控制器的动作时不需要指定 :controller 选项,因为 Rails 默认使用当前控制器。
672+
TIP: 链接到当前控制器的动作时不需要指定 `:controller` 选项,因为 Rails 默认使用当前控制器。
673+
674+
TIP: 在开发环境中(默认情况下我们是在开发环境中工作),Rails 针对每个浏览器请求都会重新加载应用,因此对应用进行修改之后不需要重启服务器。
675+
676+
### 添加验证
677+
678+
`app/models/article.rb` 模型文件简单到只有两行代码:
679+
680+
```ruby
681+
class Article < ApplicationRecord
682+
end
683+
```
684+
685+
虽然这个文件中代码很少,但请注意 `Article` 类继承自 `ApplicationRecord` 类,而 `ApplicationRecord` 类继承自 `ActiveRecord::Base` 类。正是 `ActiveRecord::Base` 类为 Rails 模型提供了大量功能,包括基本的数据库 CRUD 操作(创建、读取、更新、删除)、数据验证,以及对复杂搜索的支持和关联多个模型的能力。
686+
687+
Rails 提供了许多方法用于验证传入模型的数据。打开 `app/models/article.rb` 文件,像下面这样修改:
688+
689+
```ruby
690+
class Article < ApplicationRecord
691+
validates :title, presence: true,
692+
length: { minimum: 5 }
693+
end
694+
```
695+
696+
添加的代码用于确保每篇文章都有标题,并且标题长度不少于 5 个字符。在 Rails 模型中可以验证多种条件,包括字段是否存在、字段是否唯一、字段的格式、关联对象是否存在,等等。关于验证的更多介绍,请参阅[active\_record\_validations.xml](active_record_validations.xml#active-record-validations)
697+
698+
现在验证已经添加完毕,如果我们在调用 `@article.save` 时传递了无效的文章数据,验证就会返回 `false`。再次打开 `app/controllers/articles_controller.rb` 文件,会看到我们并没有在 `create` 动作中检查 `@article.save` 的调用结果。在这里如果 `@article.save` 失败了,就需要把表单再次显示给用户。为此,需要像下面这样修改 `app/controllers/articles_controller.rb` 文件中的 `new``create` 动作:
699+
700+
```ruby
701+
def new
702+
@article = Article.new
703+
end
704+
705+
def create
706+
@article = Article.new(article_params)
707+
708+
if @article.save
709+
redirect_to @article
710+
else
711+
render 'new'
712+
end
713+
end
714+
715+
private
716+
def article_params
717+
params.require(:article).permit(:title, :text)
718+
end
719+
```
720+
721+
在上面的代码中,我们在 `new` 动作中创建了新的实例变量 `@article`,稍后你就会知道为什么要这样做。
722+
723+
注意在 `create` 动作中,当 `save` 返回 `false` 时,我们用 `render` 代替了 `redirect_to`。使用 `render` 方法是为了把 `@article` 对象回传给 `new` 模板。这里渲染操作是在提交表单的这个请求中完成的,而 `redirect_to` 会告诉浏览器发起另一个请求。
724+
725+
刷新 <http://localhost:3000/articles/new>,试着提交一篇没有标题的文章,Rails 会返回这个表单,但这种处理方式没有多大用处,更好的做法是告诉用户哪里出错了。为此需要修改 `app/views/articles/new.html.erb` 文件,添加显示错误信息的代码:
726+
727+
```erb
728+
<%= form_for :article, url: articles_path do |f| %>
729+
730+
<% if @article.errors.any? %>
731+
<div id="error_explanation">
732+
<h2>
733+
<%= pluralize(@article.errors.count, "error") %> prohibited
734+
this article from being saved:
735+
</h2>
736+
<ul>
737+
<% @article.errors.full_messages.each do |msg| %>
738+
<li><%= msg %></li>
739+
<% end %>
740+
</ul>
741+
</div>
742+
<% end %>
743+
744+
<p>
745+
<%= f.label :title %><br>
746+
<%= f.text_field :title %>
747+
</p>
748+
749+
<p>
750+
<%= f.label :text %><br>
751+
<%= f.text_area :text %>
752+
</p>
753+
754+
<p>
755+
<%= f.submit %>
756+
</p>
757+
758+
<% end %>
759+
760+
<%= link_to 'Back', articles_path %>
761+
```
762+
763+
上面我们添加了一些代码。我们使用 `@article.errors.any?` 检查是否有错误,如果有错误就使用 `@article.errors.full_messages` 列出所有错误信息。
764+
765+
`pluralize` 是 Rails 提供的辅助方法,接受一个数字和一个字符串作为参数。如果数字比 1 大,字符串会被自动转换为复数形式。
766+
767+
`ArticlesController` 中添加 `@article = Article.new` 是因为如果不这样做,在视图中 `@article` 的值就会是 `nil`,这样在调用 `@article.errors.any?` 时就会抛出错误。
768+
769+
TIP: Rails 会自动用 div 包围含有错误信息的字段,并为这些 div 添加 `field_with_errors` 类。我们可以定义 CSS 规则突出显示错误信息。
770+
771+
当我们再次访问 <http://localhost:3000/articles/new>,试着提交一篇没有标题的文章,就会看到友好的错误信息。
772+
773+
![出错的表单](form_with_errors.png)
774+
775+
### 更新文章
776+
777+
我们已经介绍了 CRUD 操作中的“CR”两种操作,下面让我们看一下“U”操作,也就是更新文章。
660778

661-
TIP 在开发环境中(默认情况下我们是在开发环境中工作),Rails 针对每个浏览器请求都会重新加载应用,因此对应用进行修改之后不需要重启服务器。
779+
第一步要在 `ArticlesController` 中添加 `edit` 动作,通常把这个动作放在 `new` 动作和 `create` 动作之间,就像下面这样:
780+
781+
```ruby
782+
def new
783+
@article = Article.new
784+
end
785+
786+
def edit
787+
@article = Article.find(params[:id])
788+
end
789+
790+
def create
791+
@article = Article.new(article_params)
792+
793+
if @article.save
794+
redirect_to @article
795+
else
796+
render 'new'
797+
end
798+
end
799+
```
800+
801+
接下来在视图中添加一个表单,这个表单类似于前文用于新建文章的表单。创建 `app/views/articles/edit.html.erb` 文件,添加下面的代码:
802+
803+
```erb
804+
<h1>Editing article</h1>
805+
806+
<%= form_for :article, url: article_path(@article), method: :patch do |f| %>
807+
808+
<% if @article.errors.any? %>
809+
<div id="error_explanation">
810+
<h2>
811+
<%= pluralize(@article.errors.count, "error") %> prohibited
812+
this article from being saved:
813+
</h2>
814+
<ul>
815+
<% @article.errors.full_messages.each do |msg| %>
816+
<li><%= msg %></li>
817+
<% end %>
818+
</ul>
819+
</div>
820+
<% end %>
821+
822+
<p>
823+
<%= f.label :title %><br>
824+
<%= f.text_field :title %>
825+
</p>
826+
827+
<p>
828+
<%= f.label :text %><br>
829+
<%= f.text_area :text %>
830+
</p>
831+
832+
<p>
833+
<%= f.submit %>
834+
</p>
835+
836+
<% end %>
837+
838+
<%= link_to 'Back', articles_path %>
839+
```
840+
841+
上面的代码把表单指向了 `update` 动作,这个动作稍后我们再来定义。
842+
843+
`method: :patch` 选项告诉 Rails 使用 `PATCH` 方法提交表单。根据 REST 协议,`PATCH` 方法是**更新**资源时使用的 HTTP 方法。
844+
845+
`form_for` 辅助方法的第一个参数可以是对象,例如 `@article``form_for` 辅助方法会用这个对象的字段来填充表单。如果传入和实例变量(`@article`)同名的符号(`:article`),也会自动产生相同效果,上面的代码使用的就是符号。关于 `form_for` 辅助方法参数的更多介绍,请参阅 [`form_for` 的文档](http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for)
846+
847+
接下来在 `app/controllers/articles_controller.rb` 文件中创建 `update` 动作,把这个动作放在 `create` 动作和 `private` 方法之间:
848+
849+
```ruby
850+
def create
851+
@article = Article.new(article_params)
852+
853+
if @article.save
854+
redirect_to @article
855+
else
856+
render 'new'
857+
end
858+
end
859+
860+
def update
861+
@article = Article.find(params[:id])
862+
863+
if @article.update(article_params)
864+
redirect_to @article
865+
else
866+
render 'edit'
867+
end
868+
end
869+
870+
private
871+
def article_params
872+
params.require(:article).permit(:title, :text)
873+
end
874+
```
875+
876+
`update` 动作用于更新已有记录,它接受一个散列作为参数,散列中包含想要更新的属性。和之前一样,如果更新文章时发生错误,就需要把表单再次显示给用户。
877+
878+
上面的代码重用了之前为 `create` 动作定义的 `article_params` 方法。
879+
880+
TIP: 不用把所有属性都传递给 `update` 方法。例如,调用 `@article.update(title: 'A new title')` 时,Rails 只更新 `title` 属性而不修改其他属性。
881+
882+
最后,我们想在文章列表中显示指向 `edit` 动作的链接。打开 `app/views/articles/index.html.erb` 文件,在 `Show` 链接后面添加 `Edit` 链接:
883+
884+
```erb
885+
<table>
886+
<tr>
887+
<th>Title</th>
888+
<th>Text</th>
889+
<th colspan="2"></th>
890+
</tr>
891+
892+
<% @articles.each do |article| %>
893+
<tr>
894+
<td><%= article.title %></td>
895+
<td><%= article.text %></td>
896+
<td><%= link_to 'Show', article_path(article) %></td>
897+
<td><%= link_to 'Edit', edit_article_path(article) %></td>
898+
</tr>
899+
<% end %>
900+
</table>
901+
```
662902

663903
接着在 `app/views/articles/show.html.erb` 模板中添加 `Edit` 链接,这样文章页面也有 `Edit` 链接了。把这个链接添加到模板底部:
664904

@@ -821,7 +1061,25 @@ end
8211061
```erb
8221062
<h1>Listing Articles</h1>
8231063
<%= link_to 'New article', new_article_path %>
824-
1064+
<table>
1065+
<tr>
1066+
<th>Title</th>
1067+
<th>Text</th>
1068+
<th colspan="3"></th>
1069+
</tr>
1070+
1071+
<% @articles.each do |article| %>
1072+
<tr>
1073+
<td><%= article.title %></td>
1074+
<td><%= article.text %></td>
1075+
<td><%= link_to 'Show', article_path(article) %></td>
1076+
<td><%= link_to 'Edit', edit_article_path(article) %></td>
1077+
<td><%= link_to 'Destroy', article_path(article),
1078+
method: :delete,
1079+
data: { confirm: 'Are you sure?' } %></td>
1080+
</tr>
1081+
<% end %>
1082+
</table>
8251083
```
8261084

8271085
在上面的代码中,`link_to` 辅助方法生成“Destroy”链接的用法有点不同,其中第二个参数是具名路由(named route),还有一些选项作为其他参数。`method: :delete``data: { confirm: 'Are you sure?' }` 选项用于设置链接的 HTML5 属性,这样点击链接后 Rails 会先向用户显示一个确认对话框,然后用 `delete` 方法发起请求。这些操作是通过 JavaScript 脚本 `jquery_ujs` 实现的,这个脚本在生成应用骨架时已经被自动包含在了应用的布局中(`app/views/layouts/application.html.erb`)。如果没有这个脚本,确认对话框就无法显示。

0 commit comments

Comments
 (0)