原文地址:https://ididitmyway.herokuapp.com/past/2010/3/30/superdo_a_sinatra_and_datamapper_to_do_list/

这个tutorial说明:怎么构建一个list app,其中要用到数据库来保存task。

tutorial概括以下技术:

  • 安装 SQLite and Datamapper
  • 连接数据库
  • 数据库中的CRUD 动作
  • REST风格的urls

我在这里主要做的是根据我的实际操作和理解,把整个过程用我熟悉的中国话记录下来,以便下次我还能根据它实现或修改这个App,仅此而已。

开始tutorial前,确保已经安装了Sinatra、Ruby和Ruby Gems。

安装 SQLite and Datamapper

这里使用SQLite作为数据库;使用Datamapper作为ORM连接数据库。

如果你在用Ubuntu/Debian系统,这样安装SQLite

  1. sudo aptitude install sqlite3
  1. gem install sqlite3-ruby -- --with-sqlite3-dir=/usr/local/lib

这样安装DataMapper GEM

  1. sudo gem install data_mapper

还有一个adapter,连接DataMapper到数据库用的

  1. sudo gem install dm-sqlite-adapter

Note:原文还有Heroku的相关设置,我省略了。

连接到数据库(可能包括:产生、连接、插入、查询、删除等等)

在项目根目录建立main.rb文件,它之后就是此App的主文件。内容如下:

  1. require 'rubygems'
  2. require 'sinatra'
  3. require 'data_mapper'
  4.  
  5. DataMapper.setup(:default,ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/development.db")
  6.  
  7. #定义数据类(model class)
  8. class Task
  9. include DataMapper::Resource #用include方式包含DM的功能,而没有使用继承
  10. property :id,Serial
  11. property :name,String
  12. property :completed_at,DateTime
  13. end
  14.  
  15. DataMapper.auto_upgrade!

bit by bit:点点滴滴

代码说明:

1. first bit(第一部分)

  1. require 'rubygems'
  2. require 'sinatra'
  3. require 'data_mapper'

  请求必要的gems。

2. next bit

  1. DataMapper.setup(:default, ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/development.db")

它是数据库连接字符串。ENV['DATABASE_URL'] || "sqlite3://#{Dir.pwd}/development.db" 在使用Heroku是首选连接到在线数据库,如果没有才会连接本地的development.db。

而且,如果你还没有产生development.db,运行以上代码会自动产生数据库文件。

3. Next part 是Task Class定义。

值得注意的是第一行定义的:id,它是unique的,且由于类型是Srial导致其auto-increment

:completed_at,DateTime这一行告诉我们:Any task with a value of nil, will not have been completed.(没设置completed的Task,其completed_at=nil)

4.Last part of code

让DataMapper更新数据库,将Task的改变提交上去。this means(通过这种方式)甚至可以把增加/删除属性(Task类的)反映到数据库中。

如果想wipe away(擦去)所有数据(?),可以用DataMapper::auto_migrate!,但是使用要小心!!!

数据库准备好了,现在可以不用web界面,在终端状态下浏览(巡视)一下你的数据库

在终端输入:

  1. irb -r ./main.rb

说明:这会打开一个irb shell,-r 参数使得.rb 文件中的代码被包含在这个shell中。在这里,你已经连接好了数据库,现在试试[新建][编辑][查找][删除]Task吧!

下面的操作都是Task Class最常用的,我直接引用原文啦

进入irb shell :

  1. >$ irb -r main.rb

First Task.all , 查看 all our tasks:

  1. $irb(main): > Task.all
  2. => [] #返回[]表示还没有

so let’s create one:

  1. $irb(main): > t = Task.new
  2. => #<Task @id=nil @name=nil @completed_at=nil>
  3. $irb(main): > t.name = "Get milk"
  4. => "Get milk"

Task.new 对象在内存中 in memory - 还要手工存入数据库 :

  1. irb(main):007:0> t.save
  2. => true

查看一下:

  1. irb(main):008:0> Task.first
  2. => #<Task @id=1 @name="Get milk" @completed_at=nil>

什么时候都可以用Task.create()创建,显然这是类方法:

  1. irb(main):009:0> Task.create(:name => "Get bananas")
  2. => #<Task @id=2 @name="Get bananas" @completed_at=nil>

Notice用这种方式创建的,不需要手工save,它已经存入数据库了。

  1. irb(main):010:0> Task.all
  2. => [#<Task @id=1 @name="Get milk" @completed_at=nil>, #<Task @id=2 @name="Get bananas" @completed_at=nil>]

Task.all返回一个集合collection,因此它的count method返回内容的数量:

  1. irb(main):011:0> Task.all.count
  2. => 2

This shows us that there are currently two tasks saved in the database.

That has covered creating and reading records in our database. Now let’s have a look at updating. Let’s say that we want to get half fat milk. First we need to find that record.

  1. irb(main):012:0> t = Task.first(:name => "Get milk") #这样会返回第一个名字是“Get milk“的记录
  2. => #<Task @id=1 @name="Get milk" @completed_at=nil>

This is an example of how to find records in the database using certain parameters. In this case we wanted the task with the name “Get milk”. This is now stored in the variable t.

更新记录有两种办法:

The first way 手工修改 && save 保存,

  1. irb(main):014:0> t.name = "Get half fat milk"
  2. => "Get half fat milk"
  3. irb(main):015:0> t.save
  4. => true
  5. irb(main):016:0> t
  6. => #<Task @id=1 @name="Get half fat milk" @completed_at=nil>

The second way 调用 update method. (它会自动将修改保存到数据库)

  1. irb(main):017:0> t.update(:name => "Get full fat milk")
  2. => true
  3. irb(main):019:0> t
  4. => #<Task @id=1 @name="Get full fat milk" @completed_at=nil>

这些都是 CRUD 操作(actions)

我们还差最后一个 Deleting 操作 (using the destroy method ):

  1. irb(main):020:0> t = Task.get(1)
  2. => #<Task @id=1 @name="Get full fat milk" @completed_at=nil>
  3. irb(main):022:0> t.destroy
  4. => true

Notice 调用 get method 找到的是id=1的task。This can only be used if you use the primary key to search for it. In this case the primary key is the id, which is 1 for this task.

We will be using this quite often later to get the tasks from unique urls. We can check that it has been deleted by asking to see all the tasks again:

  1. irb(main):023:0> Task.all
  2. => [#<Task @id=2 @name="Get bananas" @completed_at=nil>]

Now we can see that only our second task to “Get bananas” is still saved in the database.

RESTful urls and CRUD Actions(URL router部分)

The web interface that we will create to interact with our database will be based on the REST principle.
根据REST原则创建的web ui 将会影响前面的db。

这里会使用http verb(动词):POST、GET、PUT、DELETE;db方面则有对应的CRUD actions。

View a task

对于每个task,最基础的URL可能是这样的:/task/:id(id是task的主键)。无论是read/update/delete都需要浏览器传递http verb。

下面创建一个handler of Views task,打开main.rb,增加代码:

  1. require 'rubygems'
  2. require 'sinatra'
  3. require 'data_mapper'
  4.  
  5. DataMapper.setup(:default,"sqlite3://#{Dir.pwd}/development.db")
  6.  
  7. #定义数据类(model class)
  8. class Task
  9. include DataMapper::Resource #用include方式包含DM的功能,而没有使用继承
  10. property :id,Serial
  11. property :name,String
  12. property :completed_at,DateTime
  13. end
  14.  
  15. #View a task
  16. get '/task/:id' do
  17. @task=Task.get(params[:id])
  18. erb :task
  19. end
  20.  
  21. DataMapper.auto_upgrade! # this must at last line

代码说明:对于新增部分(灰色背景的代码),{@task=Task.get(params[:id])}通过URL(/task/:id)其中的id会得到一个task,并放在对象字段@task中。

  1. erb :task sinatra显示一个task view(使用erb模板),现在还没有这个模板,所以下面创建此模板文件(./views/task.erb),模板文件应该放在views目录(这是默认配置决定的),内容:
  1. <h2><%= @task.name%></h2>

task.erb模板只能显示task name内容,如果有一个网站框架的模板就太帅了,现在创建一个名叫layout.erb的模板文件:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>To Do List</title>
  5. <meta charset="utf-8"/>
  6. </head>
  7.  
  8. <body>
  9. <h1>To Do List</h1>
  10. <%= yield%><!-- task.erb etc. files entried into here-->
  11. </body>
  12. </html>

呼~~,现在可以看看你上面都干了什么了,在终端启动主文件吧

  1. ruby main.rb

待启动后,浏览器导航地址http://localhost:4567/task/2,看看有啥!呵呵

Create a new Tasks(using a form)

Create action一般都分成两个handler来处理:

  • 一个显示(输入)表单,名叫“new";
  • 另一个处理创建task动作。

首先从显示窗体的new handler开始,用户用URL(/task/new)就能显示窗体

这里注意:新代码要放在view handler前面。

  1. #new handler - display input form
  2. get '/task/new' do
  3. erb :new
  4. end

new views的模板new.erb

  1. <form action="/task/create" method="post">
  2. <input type="text" name="name" id="name">
  3. <input type="submit" value="Add TAsk!"/>
  4. </form>

Sinatra+SQLite3+DataMapper - 十分完整的tutorial - “Superdo”的更多相关文章

  1. Sqlite3 设置插入触发器

    需求: 数据库中表t_VerifyCsmDetail需要最多保存10W条记录,超出时删除最旧的那一条. 思路:设置插入触发器.插入前先判断表中记录总数,如果大于99999条,则删除最旧的一条记录. 代 ...

  2. linux 内核邮件列表

    第一节 - 一般性问题 1. 为什么有些时候使用“GNU/Linux"而另一些时候使用“Linux”? 答:在这个FAQ中,我们尝试使用“linux”或者“linux kernel”来表示内 ...

  3. matlab中,在灰度解剖图上叠加阈值图,by by DR. Rajeev Raizada

    1.参考 reference 1. tutorial主页:http://www.bcs.rochester.edu/people/raizada/fmri-matlab.htm. 2.speech_b ...

  4. 利用matlab编写实现显示fmri切片slice图像 混合显示 不同侧面显示 可叠加t检验图显示 by DR. Rajeev Raizada

    1.参考 reference 1. tutorial主页:http://www.bcs.rochester.edu/people/raizada/fmri-matlab.htm. 2.speech_b ...

  5. flask tutorial => make a blog :) flask 搭建博客系统从零开始!

    please follow the tutorial from the official site :) http://flask.pocoo.org/docs/ You could download ...

  6. Flask:操作SQLite3(0.1)

    Windows 10家庭中文版,Python 3.6.4,Flask 1.0.2 本文介绍了第一次在Flask框架中操作SQLite3数据库的测试,参考了官网的文档Using SQLite 3 wit ...

  7. [译]The Python Tutorial#10. Brief Tour of the Standard Library

    [译]The Python Tutorial#Brief Tour of the Standard Library 10.1 Operating System Interface os模块为与操作系统 ...

  8. python 3.7.5 官方tutorial 学习笔记

    用了好久python,还没有完整看过官方的tutorial,这几天抽空看了下,还是学到些东西 --- Table of Contents 1. 课前甜点 2. 使用 Python 解释器 2.1. 调 ...

  9. SQLite3源程序分析之查询处理及优化

    前言 查询处理及优化是关系数据库得以流行的根本原因,也是关系数据库系统最核心的技术之一.SQLite的查询处理模块很精致,而且很容易移植到不支持SQL的存储引擎(Berkeley DB最新的版本已经将 ...

随机推荐

  1. 框架,公共模块,unified思想

    最近两周一直在加班加点refactor代码,贡献了2014年最后一个周末和2015年元旦三天假期,终于赶在了sprint结束之前完成. 可见,这个sprint做的并不理想! 项目逻辑本身并不复杂,从数 ...

  2. 【Algorithm】堆排,C++实现

    对一个数组中的元素按照顺序构建二叉树,就形成了一个(二叉)堆.(二叉树是虚拟的,并不是真的建立二叉树) 表示堆的数组A有两个重要属性:A.heapSize,表示堆里面有多少元素,数组里有多少元素在堆里 ...

  3. Java学习-036-JavaWeb_005 -- JSP 动作标识 - forward

    JSP 动作主要作用是根据指定的动作进行相应的处理. 一.param 动作 用来给 HTML 文件和 JSP 文件传递参数的,经常和 forward.include.plugin 动作结合使用,语法格 ...

  4. linux matlab2013b 安装教程

    链接:http://pan.baidu.com/s/1pJE6R2b 密码:shfy 1. 解压缩“Mathworks Matlab R2013b Linux.rar”(无需密码),得到“Mathwo ...

  5. npy in c

    https://jcastellssala.com/2014/02/01/npy-in-c/

  6. jenkins邮件模板

    步骤 1.在jenkins主目录中新建一个模板文件夹 命名为:email-templates 3.把模板代码放入到模板文件夹  with_results.groovy 4.设置邮件发送模板配置 5.配 ...

  7. Vue.2.0.5-插件

    开发插件 插件通常会为Vue添加全局功能.插件的范围没有限制--一般有下面几种: 添加全局方法或者属性,如: vue-element 添加全局资源:指令/过滤器/过渡等,如 vue-touch 通过全 ...

  8. Unable to get setting value Parameter name: profileName

    Today when I am building my application, everything works well but when I try to run Azure Worker Ro ...

  9. ssh隧道技术

    大家都知道SSH是一种安全的传输协议,用在连接服务器上比较多.不过其实除了这个功能,它的隧道转发功能更是吸引人.下面是个人根据自己的需求以及在网上查找的资料配合自己的实际操作所得到的一些心得. SSH ...

  10. 使用duplicate target database ... from active database复制数据库

    使用duplicate target database ... from active database复制数据库 source db:ora11auxiliary db:dupdb 1.修改监听文件 ...