zoukankan      html  css  js  c++  java
  • Ruby Rails学习中:有点内容的静态页面

    续上篇:

    一. 有点内容的静态页面

    rails new 命令创建了一个布局文件, 不过现在最好不用。我们重命名这个文件:

    $ mv app/views/layouts/application.html.erb layout_file    # 临时改动

    注:在真实的应用中你不需要这么做,不过没有这个文件能让你更好地理解它的作用。

    注:关于表题所需变动的部分

    1. 添加标题

    添加标题之前,我们要知道网页的一般结构,如下图所示:

    我们要使用 assert_select 方法分别为app/views/static_pages中的每个标题编写简单的测试。assert_select 方法的作用是检查有没有指定的 HTML 标签。这种方法有时也叫“选择符”(selector),因此才为这个方法取这么一个名称。

    assert_select "title", "Home | Ruby on Rails Tutorial Sample App"

    这行代码的作用是检查有没有 <title> 标签,以及其中的内容是不是“Home | Ruby on Rails Tutorial Sample App”字符串。把这样的代码分别放到三个页面的测试中。

    接下来测试 RED

    rails test

    注:测试结果表明三个都没有

    2.添加页面标题 Green

    打开文件:app/views/static_pages/home.html.erb(具有完整 HTML 结构的首页)

    打开文件:app/views/static_pages/help.html.erb(具有完整 HTML 结构的“帮助”页面)

    打开文件:app/views/static_pages/about.html.erb(具有完整 HTML 结构的“关于”页面)

    现在再测试(Green):

    注:通过!不过你可能注意到了, StaticPages 控制器的测试中有些重复,每个标题测试中都有“Ru-by on Rails Tutorial Sample App”。我们可以使用特殊的函数 setup 去除重复。这个函数在每个测试运行之前执行。下面有具体说明自己确认代码清单中的测试仍能通过。

    打开文件:test/controllers/static_pages_controller_test.rb(使用一个基标题的 StaticPages 控制器测试)

    3.布局和嵌入式 Ruby(重构)

    到目前为止,我们已经做了很多事情,我们使用 Rails 控制器和动作生成了三个可用的页面,不过这些页面中的内容都是纯静态的 HTML,没有体现出 Rails 的强大之处。而且,代码中有大量重复:
    • 页面的标题几乎(但不完全)是一模一样的;
    • 每个标题中都有“Ruby on Rails Tutorial Sample App”;
    • 整个 HTML 结构在每个页面都重复地出现了。
    重复的代码违反了很重要的“不要自我重复”(Don’t Repeat Yourself,简称 DRY)原则。本节要遵照 DRY 原则,去掉重复的代码。最后,我们要运行前面编写的测试,确认显示的标题仍然正确。不过,去除重复的第一步却是要增加一些代码,让页面的标题看起来是一样的。这样我们就能更容易地去掉重复的代码了。在这个过程中,我们要在视图中使用嵌入式 Ruby(Embedded Ruby)。既然首页、“帮助”页面和“关于”页面的标题中有一个变动的部分,那我们就使用 Rails 提供的一个特别的函数 provide ,在每个页面中设定不同的标题。通过把 home.html.erb 视图中标题的“Home”换成下图所示的代码,我们可以看一下这个函数的作用。

    打开文件:app/views/static_pages/home.html.erb(标题中使用了嵌入式 Ruby 代码的首页视图)

    在这段代码中我们第一次使用了嵌入式 Ruby(简称 ERb)。(现在你应该知道为什么 HTML 视图文件的扩展名是 .html.erb 了。)ERb 是为网页添加动态内容使用的主要模板系统。下面的代码
    <% provide(:title, 'Home') %>
    通过 <% ... %> 调用 Rails 提供的 provide 函数,把字符串 "Home" 赋给 :title 。然后,在标题中,我们使用类似的符号 <%= ... %> ,通过 Ruby 的 yield 函数把标题插入模板中: 
    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
    (这两种嵌入式 Ruby 代码的区别在于, <% ... %> 只执行执行其中的代码; <%= ... %> 除了执行其中的代码,还会把执行的结果插入模板中。)最终得到的页面跟以前一样,不过,现在标题中变动的部分通过 ERb 动态生成。

    注:相当于Python Django框架中的模板语法

    现在运行一下测试,还是能通过的(Green

    注:既然可以,那就把"帮助"和"关于"页面也给改了呗

    打开文件:app/views/static_pages/help.html.erb(标题中使用了嵌入式 Ruby 代码的“帮助”页面视图)

    打开文件:app/views/static_pages/about.html.erb(标题中使用了嵌入式 Ruby 代码的“关于”页面视图)

    至此,我们把页面标题中的变动部分都换成了 ERb。现在,各个页面的内容类似下面这样:

    注:也就是说,所有页面的结构都是一样的,包括 title 标签中的内容,只有 body 标签中的内容有些差别

    为了提取出共用的结构,Rails 提供了一个特别的布局文件,名为 application.html.erb 。我们在 3.4 节的开头重命名了这个文件,现在改回来:

    $ mv layout_file app/views/layouts/application.html.erb

    若想使用这个布局,我们要把默认的标题换成前面几段代码中使用的嵌入式 Ruby:

    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>

    修改后得到的布局文件如下所示。

    注意,其中有一行比较特殊:
    <%= yield %>
    这行代码的作用是,把每个页面的内容插入布局中。没必要了解它的具体实现过程, 我们只需知道, 在布局中使用这行代码后, 访问 /static_pages/home 时会把 home.html.erb 中的内容转换成 HTML,然后插入 <%=yield %> 所在的位置。

    还要注意,默认的 Rails 布局文件中有下面这几行代码:
    <%= csrf_meta_tags %> <%= stylesheet_link_tag ... %> <%= javascript_include_tag "application", ... %> 这几行代码的作用是, 引入应用的样式表和 JavaScript 文件;Rails 提供的 csrf_meta_tags 方法,作用是避免跨站请求伪造(Cross-Site Request Forgery,简称 CSRF,一种恶意网络攻击)。 现在, "首页", "帮助", "关于"的内容还是和布局文件中的 HTML 结构类似,所以我们要把完整的结构删除, 只保留需要的内容。清理后的视图如下所示

    打开文件:app/views/static_pages/home.html.erb(去除完整的 HTML 结构后的首页)

    打开文件:app/views/static_pages/help.html.erb(去除完整的 HTML 结构后的“帮助”页面)

    打开文件:app/views/static_pages/about.html.erb(去除完整的 HTML 结构后的“关于”页面)

    注:修改这几个视图后, “首页”, “帮助”页面和“关于”页面显示的内容还和之前一样, 但是没有多少重复内容了。

    经验告诉我们, 即便是十分简单的重构, 也容易出错, 所以才要认真编写测试组件。有了测试, 我们就无需手动检查每个页面, 看有没有错误。初期阶段手动检查还不算难, 但是当应用不断变大之后, 情况就不同了。我们只需验证测试组件是否还能通过即可:

    注:测试不能证明代码完全正确,但至少能提高正确的可能性,而且还提供了安全防护措施,能避免以后出问题。

    自己尝试着添加一个“联系”页面:

    4.设置根路由

    我们修改了网站中的页面,也顺利开始编写测试了,在继续之前,我们要设置应用的根路由。与前面的做法一样,我们要修改 routes.rb 文件,把根路径 / 指向我们选择的页面。这里我们要指向前面创建的首页。(我还建议把前面节添加的 hello 动作从 Application 控制器中删除。)如下所示,我们要把 root 规则由
    root 'application#hello'
    改成
    root 'static_pages#home'
    这样对 / 的请求就交给 StaticPages 控制器的 home 动作处理了。修改路由后,首页如下图所示。

     添加上图中的根路由后, 会得到一个名为 root_url 的辅助方法(与 static_pages_home_url类似)。修改测试文件, 测试根路由

    。。。

    今天先到这吧,做个总结:

    二. 总结

    • 执行 rails generate controller ControllerName <optional action names> 命令会生成一个新控制器;
    • 在 config/routes.rb 文件中定义了新路由;
    • Rails 的视图中可以包含静态 HTML 或嵌入式 Ruby(ERb);
    • 测试组件能驱动我们开发新功能, 给我们重构的自信, 还能捕获回归;
    • 测试驱动开发使用“遇红-变绿-重构”循环;
    • Rails 的布局定义应用中页面共用的模板, 可以去除重复。
  • 相关阅读:
    洛谷p1017 进制转换(2000noip提高组)
    Personal Training of RDC
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Eurasia
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Peterhof.
    Asia Hong Kong Regional Contest 2019
    XVIII Open Cup named after E.V. Pankratiev. Grand Prix of Siberia
    XVIII Open Cup named after E.V. Pankratiev. Ukrainian Grand Prix.
    XVIII Open Cup named after E.V. Pankratiev. GP of SPb
    卜题仓库
    2014 ACM-ICPC Vietnam National First Round
  • 原文地址:https://www.cnblogs.com/rixian/p/11672258.html
Copyright © 2011-2022 走看看