《Agile Web Development with Rails》抄书笔记(07):数据校验
《Agile Web Development with Rails》抄书笔记系列
“《Agile Web Development with Rails》抄书笔记系列”目录
上两节,我们简单创建了一个商品维护的应用。但是,在想应用中添加商品信息时,我们必须确保商品信息的正确性!那么,如何来实现呢?也许你已经想到了,数据校验!这节我们就给大家介绍一下数据校验。
对于任何程序来说,数据校验都是必须的。比如,我们注册邮箱,邮箱名不能为空;在论坛注册账号,注册名不能为空,当然有些是邮箱等不能为空。同样,对于,我们这个学习程序”Depot购物网”,也有同样的要求。比如,产品名称不能为空;产品价格不能为0,否则只能”赔钱”!
这样,问题就来了:
- 在什么地方加数据校验?
- 该如何进行数据校验?
从我们上一章的学习来看,Model层是代码和数据库之间的沟通信道。无论是从数据库中读取数据,还是向数据库中插入数据,都要通过Model来完成。所以,Model是设置数据校验规则的理想选择!不管数据是从表单中获取还是在程序中操控,都能得到一致的校验。这样,在存入数据库之前,就校验了数据的一致性,能有效防止无效数据混入到数据库中去。
D呱呱
本节内容相关的源代码:
非空校验
打开上一章创建的Product类(app/models/product.rb):
class Product < ActiveRecord::Base attr_accessible :description, :image_url, :price, :title end
在其中添加如下一行代码:
validates :description, :image_url, :title, presence: true
validates()方法是Rails的标准校验方法,可以校验一个到多个字段。presence: true表示校验的所有字段不能为空。保存后,大家可以打开http://127.0.0.1:3000/products/new试试效果。
测试后,大家会发现,Rails做的真是贴心:错误的字段都高亮显示了。另外,你还会发现,虽然你修改了代码,但是不需要重启服务器就能生效!这意味着,无需重启,修改后的代码可以立即加载运行,可以确保运行的代码始终都是最新的。(这个在测试环境下是这样的,但是在)
数字校验
下面,我们对价格price进行校验。
首先,价格必须是一个数字;另外,我们不能赔钱赚吆喝啊!价格必须大于0.01分(学习第一,就不要考虑是美分还是RMB了),那么我们的校验如何写呢?
validates :price, numericality: {greater_than_or_equal_to: 0.01}
D呱呱
D瓜哥补充一句:设置数字精度的时候,要注意和数据库中的精度保持一致。
D瓜哥夸奖一下:方法名字起的很好:见文知意。可以,就是有点长。
唯一性校验
我们不想一种产品在数据库中有两条记录,保持产品名称的唯一性是一个可行的手段。uniqueness校验能检查、并确保数据的唯一性。
validates :title, uniqueness: true
图片后缀校验
最后,我们还需要检查一下图片URL的合法性,确保图片名称的后缀是正确的图片后缀。对于处理字符串来说,正则表达式是再好不过的选择了。所以,我们来使用正则表达式来校验图片名称的合法性。我们要求,只能使用以.gif, .jpg和.png结尾的图片,则校验方法如下:
validates :image_url, allow_blank: true, format: { with: %r{\.(gif|jpg|png)$}i, message: 'must be a URLforGIF, JPGor PNGimage.' }
测试
最后,我们使用Rails集成的测试套件来测试一下我们刚刚的完成的数据校验的情况。直接在命令行中运行如下命令:
rake test
则报两个错误,提示如下:
Finished tests in 0.520030s, 13.4608 tests/s, 17.3067 assertions/s. 1) Failure: test_should_create_product(ProductsControllerTest) [F:/depot/test/functional/products_controller_test.rb:20]: "Product.count" didn't change by 1. <3> expected but was <2>. 2) Failure: test_should_update_product(ProductsControllerTest) [F:/depot/test/functional/products_controller_test.rb:39]: Expected response to be a <:redirect>, but was <200> 7 tests, 9 assertions, 2 failures, 0 errors, 0 skips
这是因为我们修改了Model字段的校验规则,但是测试用例别没有实时修改。所以,我们需要修改一下测试用例的代码:
setup do @product = products(:one) @update = { title: 'Lorem Ipsum', description: 'Wibbles are fun!', image_url: 'lorm.jpg', price: 19.95 } end test "should create product" do assert_difference('Product.count') do post :create, product: @update end assert_redirected_to product_path(assigns(:product)) end test "should update product" do put :update, id: @product, product: @update assert_redirected_to product_path(assigns(:product)) end
再次测试,应就OK了。哈哈下一节,D瓜哥给大家介绍“单元测试”。
D呱呱
这节内容以及接下来的几节内容是前一段时间整理的,和前几篇的风格差异有点大。为了弥补给大家的不爽,D瓜哥给大家推荐一些不错的Rails资源:
- Ruby on Rails 實戰聖經,ihower整理的一个教程,非常简明扼要地介绍了一下Rails。非常棒,推荐!
- Ruby on Rails Tutorial中文版,这个教程也非常棒。是网友刚刚翻译过来的,D瓜哥看了第一章,觉得挺不错。另外,D瓜哥以后准备把这本书中的一些比较好的实践,在这个”抄书笔记”中实践一下。
- Rails Searchable API,网友zhiliang推荐,也许你到现在还没有超过Rails的API吧。没事,D瓜哥也是。再吐槽一下,没有Java JDK的API好使。
- Rails API Documentation,貌似Rails官方的API。
- API Dock,网友zhiliang推荐,但是D瓜哥还没学会怎么用。
- Dash,网友yedingding推荐。可惜D瓜哥没有Mac,只能眼馋一下。
原文链接:https://wordpress.diguage.com/archives/13.html
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。
如果使用Rails4的话在非空校验那里attr_accessible这个会报错
在官网说明中到看下面
Rails 4.0 has removed attr_accessible and attr_protected feature in favor of Strong Parameters. You can use the Protected Attributes gem for a smooth upgrade path.
所以我们要到我们项目的Gemfile文件里添加一行gem ‘protected_attributes’,再次运行bundle。或是使用gem install protected_attributes命令安装protected_attributes
在Rails4中,attr_accessible这种方式被废了,你查查最新的方式是怎么样的吧。变化很大的。呵呵
在Rails4中,attr_accessible这种方式被废了,你查查最新的方式是怎么样的吧