首页 > Web开发, 动态语言, 挨踢(IT) > 《Agile Web Development with Rails》抄书笔记(07):数据校验

《Agile Web Development with Rails》抄书笔记(07):数据校验

2013年5月1日 发表评论 阅读评论 529 人阅读    

《Agile Web Development with Rails》抄书笔记系列

  “《Agile Web Development with Rails》抄书笔记系列”目录

  上两节,我们简单创建了一个商品维护的应用。但是,在想应用中添加商品信息时,我们必须确保商品信息的正确性!那么,如何来实现呢?也许你已经想到了,数据校验!这节我们就给大家介绍一下数据校验。

  对于任何程序来说,数据校验都是必须的。比如,我们注册邮箱,邮箱名不能为空;在论坛注册账号,注册名不能为空,当然有些是邮箱等不能为空。同样,对于,我们这个学习程序”Depot购物网”,也有同样的要求。比如,产品名称不能为空;产品价格不能为0,否则只能”赔钱”!

  这样,问题就来了:

  1. 在什么地方加数据校验?
  2. 该如何进行数据校验?

  从我们上一章的学习来看,Model层是代码和数据库之间的沟通信道。无论是从数据库中读取数据,还是向数据库中插入数据,都要通过Model来完成。所以,Model是设置数据校验规则的理想选择!不管数据是从表单中获取还是在程序中操控,都能得到一致的校验。这样,在存入数据库之前,就校验了数据的一致性,能有效防止无效数据混入到数据库中去。

D呱呱

  本节内容相关的源代码:

  1. 本节开始之前:https://github.com/diguage/depot/tree/v-06.2
  2. 本节结束之后:https://github.com/diguage/depot/tree/v-07.1

非空校验

  打开上一章创建的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资源:

  1. Ruby on Rails 實戰聖經ihower整理的一个教程,非常简明扼要地介绍了一下Rails。非常棒,推荐!
  2. Ruby on Rails Tutorial中文版,这个教程也非常棒。是网友刚刚翻译过来的,D瓜哥看了第一章,觉得挺不错。另外,D瓜哥以后准备把这本书中的一些比较好的实践,在这个”抄书笔记”中实践一下。
  3. Rails Searchable API,网友zhiliang推荐,也许你到现在还没有超过Rails的API吧。没事,D瓜哥也是。再吐槽一下,没有Java JDK的API好使。
  4. Rails API Documentation,貌似Rails官方的API。
  5. API Dock,网友zhiliang推荐,但是D瓜哥还没学会怎么用。
  6. Dash,网友yedingding推荐。可惜D瓜哥没有Mac,只能眼馋一下。


作 者: D瓜哥,https://www.diguage.com/
原文链接:https://www.diguage.com/archives/13.html
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

  1. topcat
    2013年9月5日16:46 | #1

    如果使用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

    • D瓜哥
      2013年9月5日17:05 | #2

      在Rails4中,attr_accessible这种方式被废了,你查查最新的方式是怎么样的吧。变化很大的。呵呵

  2. 2014年4月28日13:03 | #3

    在Rails4中,attr_accessible这种方式被废了,你查查最新的方式是怎么样的吧

  1. 2013年5月24日17:02 | #1
  2. 2013年6月24日23:58 | #2