III 任务C:商品目录显示
任务列表:
·编写用户视力
·使用页面布局来装点页面
·集成CSS
·使用帮助程序
·编写功能测试程序
客户接下来想先看下从买家的角度,这个应用程序是什么样子。那我们要做的就是创建简单的商品目录显示网页。
一、迭代C1:创建商品目录清单
前面创建了商品(product)控制器,卖家可以用来管理depot程序。现在我们需要创建另外一个控制器,用来与消费者互动,称为store(商店)
(我现在使用aptana studio3工具开发,以下执行的命令是在这上面执行的。基本和dos一样,但是更像是linux)
Administrator@JARRY /e/works/ruby/depot (master) $ rails generate controller store index SECURITY WARNING: No secret option provided to Rack::Session::Cookie. This poses a security threat. It is strongly recommended that you provide a secret to prevent exploits that may be possible from crafted cookies. This will not be supported in future versions of Rack, and future versions will even invalidate your existing user cookies. Called from: d:/dev/RailsInstaller/Ruby1.9.3/lib/ruby/gems/1.9.1/gems/actionpack-3.2.1/lib/action_dispatch/middleware/ session/abstract_store.rb:28:in `initialize'. create app/controllers/store_controller.rb route get "store/index" invoke erb create app/views/store create app/views/store/index.html.erb invoke test_unit create test/functional/store_controller_test.rb invoke helper create app/helpers/store_helper.rb invoke test_unit create test/unit/helpers/store_helper_test.rb invoke assets invoke coffee create app/assets/javascripts/store.js.coffee invoke scss create app/assets/stylesheets/store.css.scss
这里创建了控制器(/app/controllers/store_controller.rb文件下的StoreController)
设置store/index为根网址
编辑/config/routes.rb文件
Depot::Application.routes.draw do get "store/index" resources :products # ... # You can have the root of your site routed with "root" # just remember to delete public/index.html. # root :to => 'welcome#index' root to: "store#index", as: "store" #add # ... end
注释中提示了要删除public/index.html,那么删除它:
Administrator@JARRY /e/works/ruby/depot (master) $ rm public/index.html
在浏览器中尝试http://localhost:3000/
需要得到商品清单而非源自数据库,且把它提供给显示清单的视图代码,这样需要修改/controllers/store_controller.rb。要在合适的抽象层面上编程,这样就先假定可以从模型中得到可销售的商品清单:
class StoreController < ApplicationController def index @products = Product.all end end
先确定下商品的显示顺序,这里用字母顺序来显示。打开模型Product添加方法default_scope,默认范围(scopes)会作用于该模型的所有查询。
/app/models/product.rb
class Product < ActiveRecord::Base default_scope order: 'title' # validates stuff ... end
接下来编写视图模板。修改/app/views/store/index.html.erb:
<% if notice %> <p id="notice"><%= notice %></p> <% end %> <h1>Your Pragmatic Catalog</h1> <% @products.each do |product| %> <div class="entry"> <% image_tag(product.image_url) %> <h3><%= product.title %></h3> <%= sanitize(product.description) %> <div class="price_line"> <span class="price"><%= product.price %></span> </div> </div> <% end %>
这里要指出的是商品属性所用的方法sanitize:它允许安全地添加HTML风格代码,使客户对这一商品属性描述内容更有兴趣。(这样会潜在安全漏洞,但是在这里商品描述都是由公司员工所创建,所以认为风险是很小的。)
刷新页面显示:
页面实在是不美观,要添加样式,但是这就需要专门的网页设计人员设计了。如需要看到比较漂亮的标题和侧边栏。
二、迭代C2:增加页面布局
通过网站页面会共享相似的页面布局--设计人员将已生成的标准模板用来填写内容。下面的工作是将这个网页装饰添加到商店的每个网页上。将这个页面布局命名为application.html.erb,在没有其他页面布局的情况下,所有控制器的视图都将使用这个布局。由于只使用单个布局,因此只需要编辑该文件就可以修改整个网页的界面外观。这里先设置一个占位页面布局,具体需要专门设计。
这个布局放到/app/views/layouts目录中,application.html.erb:
<!-- START:head --> <!DOCTYPE html> <html> <head> <!-- START_HIGHLIGHT --> <title>Pragprog Books Online Store</title> <!-- END_HIGHLIGHT --> <%= stylesheet_link_tag "application", media: "all" %> <%= javascript_include_tag :defaults %><!-- <label id="code.jlt"/> --> <%= csrf_meta_tags %><!-- <label id="code.csrf"/> --> </head> <!-- END:head --> <body class="store"> <!-- START_HIGHLIGHT --> <div id="banner"> <%= image_tag("logo.png") %> <%= @page_title || "Pragmatic Bookshelf" %><!-- <label id="code.depot.e.title"/> --> </div> <div id="columns"> <div id="side"> <ul> <li><a href="http://www....">Home</a></li> <li><a href="http://www..../faq">Questions</a></li> <li><a href="http://www..../news">News</a></li> <li><a href="http://www..../contact">Contact</a></li> </ul> </div> <div id="main"> <!-- END_HIGHLIGHT --> <%= yield %><!-- <label id="code.depot.e.include"/> --> <!-- START_HIGHLIGHT --> </div> </div> <!-- END_HIGHLIGHT --> </body> </html>
更改application.css
/* * This is a manifest file that'll be compiled into application.css, which will include all the files * listed below. * * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path. * * You're free to add application-wide styles to this file and they'll appear at the top of the * compiled file, but it's generally better to create a new file per style scope. * *= require_self *= require_tree . */ /* START_HIGHLIGHT */ #banner { background: #9c9; padding: 10px; border-bottom: 2px solid; font: small-caps 40px/40px "Times New Roman", serif; color: #282; text-align: center; } #banner img { float: left; } #notice { color: #000 !important; border: 2px solid red; padding: 1em; margin-bottom: 2em; background-color: #f0f0f0; font: bold smaller sans-serif; } #columns { background: #141; } #main { margin-left: 17em; padding: 1em; background: white; } #side { float: left; padding: 1em 2em; width: 13em; background: #141; } #side ul { padding: 0; } #side li { list-style: none; } #side a { color: #bfb; font-size: small; } /* END_HIGHLIGHT */
刷新浏览器观看效果:
现在页面并不美观,但是有个大概的样子,可以给客户看了。
三、迭代C3:用帮助函数来调整价格格式
细看上图发现一个小问题,商品价格在数据库中都是以数字形式保存的。现在我RMB形式显示如价格12.34,就显示为¥12.34;13则显示为¥13.00
Ruby提供了sprintf函数,可以用来对价格进行格式化。可以直接在视图中使用:
<span class="price"><%= sprintf("¥%0.02f",product.price) %></span>
但是这样做以后想国际化这个应用就有维护的问题了。比如 要用美元显示了。
如果有个帮助函数把价格转换成货币格式就好了。恰好Rails就有这样的内置函数:number_to_curreny
参考:http://api.rubyonrails.org/
http://blog.chinaunix.net/uid-25231750-id-153630.html
在视图中如下使用:
<span class="price"><%= number_to_currency(product.price, unit: "¥") %></span>
刷新页面
四、迭代C4:控制器功能测试
在添加新功能之后应该为它编写和运行测试。特别是在添加逻辑到模型的行为之后。
首先确定修改之后是否破坏了什么。我们运行一下测试:
rake test
一切正常,说明增加修改没有破坏任何东西,但是接下来需要测试刚刚加上的功能。
之前所做的模型单元测试看上去是相当清楚的。调用方法,且比较返回值和期待值。但是当前在浏览器中所涉及的不仅是服务器处理讲求,而且用户也注视着响应。我们需要功能测试,这能验证模型、视图、控制器是否在一起正常工作。
先看下rails生成了什么。
/test/functional/store_controller_test.rb:
require 'test_helper' class StoreControllerTest < ActionController::TestCase test "should get index" do get :index assert_response :success end end
这个should get index测试得到了索引并断言期待成功响应。但是还想验证响应是否包含了布局、商品信息和数字格式,看如下代码:
# encoding:utf-8 require 'test_helper' class StoreControllerTest < ActionController::TestCase test "should get index" do get :index assert_response :success assert_select '#columns #side a', minimum: 4 assert_select '#main .entry', 3 assert_select 'h3', 'Programming Ruby 1.9' assert_select '.price', /\¥[,\d]+\.\d\d/ end end
上面添加的4行代码是通过css选择器表示法,查看所返回的HTML代码。
第一个选择测试寻找的是名为a的元素,在id值为side的元素中包含了该元素,而在id值为columns的元素中又包含这个id值为side的元素。这个测试是验证所有满足以上条件的这样的元素中最小值为4.
第二个验证在页面的主要部分有3个类名为entry元素
第三个验证存在具有Ruby书名的h3元素
第四个验证价格格式是否正确。
这些断言都是基于静态测试中的测试数据:
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html one: title: MyString description: MyText image_url: MyString price: 9.99 two: title: MyString description: MyText image_url: MyString price: 9.99 ruby: title: Programming Ruby 1.9 description: Ruby is the fastest growing and most exciting dynamic language out there. If you need to get working programs delivered fast, you should add Ruby to your toolbox. price: 49.50 image_url: ruby.png #END:ruby
验证和功能测试都仅测试控制器的行为:它们还会影响任何对象,因为该对象已经在数据库或静态测试中。在之前两个商品有相同的标题。这样的数据将不会导致任何问题,而且将不会察觉到修改和保存这些记录,还会对现有的对象门生任何影响。
现在运行功能测试:
rake test:functionals
相关推荐
- **周二**:创建第一个应用程序,学习如何处理文件、生成器和脚本。 - **周三**:掌握迁移、ActiveRecord、ActionController和ActionView的基本用法。 - **周四**:深入了解ActiveRecord的关联、验证和回调机制;...
### Ruby on Rails Guides v2 - Ruby on Rails 4.2.5 #### 一、重要概念及基础假设 - **重要概念**:本指南旨在帮助读者深入理解Ruby on Rails(以下简称Rails)4.2.5版本的核心功能与最佳实践。 - **基础假设**:...
在这个全球互联的世界中,计算机编程和 Web 应用程序开发都在迅猛发展,我很期待能为中国的开发者提供 Ruby on Rails 培训。学习英语这门世界语言是很重要的,但先通过母语学习往往会更有效果。正因为这样,当看到 ...
Ruby on Rails,简称Rails,是基于Ruby编程语言的一个开源Web应用程序框架,它遵循MVC(模型-视图-控制器)架构模式,旨在提高开发效率和代码的可读性。Rails以其“约定优于配置”(Convention over Configuration)...
Ruby on Rails,简称ROR或Rails,是一款基于Ruby语言的开源Web应用框架,它遵循Model-View-Controller(MVC)架构模式,旨在提高开发效率和代码可读性。本教程“Ruby on Rails 教程 - 201406”可能是针对2014年6月时...
Ruby on Rails,简称Rails,是一款基于Ruby语言的开源Web应用框架,它遵循MVC(Model-View-Controller)架构模式,旨在简化Web应用程序的开发。Rails由David Heinemeier Hansson于2004年创建,它提倡“约定优于配置...
- **第一个应用:** 创建完应用后,可以通过编写简单的代码来测试Rails的基本功能。例如,创建一个简单的“Hello, Rails!”页面,用来验证环境配置是否正确。 - **链接页面:** Rails提供了强大的路由机制,用于定义...
接下来,书中会详细解释Rails的安装和配置过程,包括环境搭建、数据库配置以及Gemfile的使用,使读者能够快速创建并运行第一个Rails应用。同时,还会讲解Rails的核心组件,如路由、控制器、模型和视图,以及它们在...
Rails在2005年发布第一个稳定版本1.0.0。 - **Rails的版本迭代**:文档中提到的v1.0.0是Rails早期的一个版本,而Rails 2.3.2和Rails 2.5是后续更迭的版本。 - **Rails的主要特性**:Rails采用了约定优于配置...
Ruby on Rails,简称Rails,是一种基于Ruby编程语言的开源Web应用程序框架,它遵循MVC(模型-视图-控制器)架构模式,旨在提高开发效率和代码的可读性。本示例源码提供了使用Ruby on Rails进行实际项目开发的具体...
### Ruby on Rails 指南 v5.0.1 中文版 #### Rails入门 - **前提条件**:为了能够顺利地开始Rails的学习之旅,读者需要具备一定的Ruby语言基础,并且对Web开发有一定的了解。 - **Rails是什么?**:Rails是一种...
Ruby on Rails,简称Rails,是由David Heinemeier Hansson创建的一个开源Web应用程序框架,它基于Ruby编程语言。这个框架以其MVC(Model-View-Controller)架构、约定优于配置(Convention over Configuration)的...
- **Rails入门**:讲解如何安装配置Ruby on Rails环境,以及创建第一个Rails应用的过程。 - **数据库交互**:教授如何在Rails应用中使用ActiveRecord来操作数据库。 - **控制器与视图**:介绍Rails中的控制器和视图...
Ruby on Rails,简称Rails,是基于Ruby编程语言的一个开源Web应用程序框架,以其“约定优于配置”(Convention over Configuration)的设计哲学和“模型-视图-控制器”(MVC)架构模式,深受开发者喜爱。这套书全集...
第一章“Ruby on Rails概述”,介绍了Ruby on Rails的基本概念和开发环境的搭建方法。通过这一章的学习,读者将对Rails框架有一个整体的认识,并了解如何搭建开发环境以及设计用户界面(UI)。 第二章“Rails中的...
4. 实践创建第一个Rails应用,了解路由、模型、控制器和视图。 5. 探索数据库操作和ActiveRecord,阅读相关章节。 6. 学习Rails的高级特性,如回调、观察者、缓存、异步处理等。 7. 熟悉测试,通过"Ruby On Rails[1]...
Ruby on Rails(简称Rails)是一个基于Ruby语言的开源Web应用程序框架,它遵循MVC(模型-视图-控制器)架构模式,旨在简化Web应用的开发过程,提高开发效率。Rails的核心理念是“约定优于配置”,这意味着在很多情况...