前言

在上一章讲述了如何进行基础的操作,比如 处理 GET 请求的 get route, 再比如下载 gem 等等方面的知识.
在这一章节,作者告诉我们如何储存、处理数据.
整个过程分三步走:

  1. 首先,当 user 提交了一个 form 之后, 我们需要 create 一个对应的 Movie 的 object.
  2. 然后,我们将 Ruby object 储存进一个格式为 .yml 的 file 中
  3. 当 user 点击一个 object 的 ID 之后,能够从 .yml 格式的 file 中得到一个新的 HTML 页面,进而获取详细信息.

1⃣️ create 一个对应的 Movie 的 object

第一步: Setting the HTML form to send a POST request

原理:两个 attribute

首先,我们需要确保 POST 请求是完整的,因此在 HTML 的 <form> tag 里,需要两个 attribute:

  1. method:即 POST 这个 HTTP method
  2. action:即提交到所在资源库的 path

格式:

<form method="post" action="/movies/create">

第二步: Setting up a post route

原理:

处理 GET 请求的 Sinatra 的 route 名字叫 get, POST 请求的叫 post.
params 是伴随 post 方法的一个参数,这个参数是一个 hash, 它包含了 form data from the request.

格式:

post('/movies/create') do
"Received: #{params.inspect}"
end

✅过程三步走的第一步

首先,当 user 提交了一个 form 之后, 我们需要 create 一个对应的 Movie 的 object.

post('/movies/create') d0
@movie = Movie.new
@movie.title = params['title']
@movie.director = params['director']
@movie.year = params['year']
end

2⃣️ 将数据存储在 .yml 格式的 file 中

关于 YAML

YAML 定义:

YAML 不是标记语言,而是一个 standard for representing objects and other data.

YAML 功能:

  1. 用于将 object 的数据储存成为字符串格式
  2. 相逆的,用于将字符串格式的内容转变为 object

与 Ruby 的关系

Ruby 中的 'yaml' 模块可以将 Ruby 中的 objects 转换为 YAML 格式的 file 储存起来.

格式:

require 'yaml'

该模块可供调用的 method

  • dump 用于将 object 转换为一个 string
  • load 用于将一个 string 转换为 object

关于 YAML::Store

‘yaml' 仅仅可以进行转换,而无法将其内容储存为一个 file在 YAML library 中包含了 YAML::Store 这个 class, 它可以将 object 储存为 disk 中的 file.

格式

调用库:

require 'yaml/store'

读写:

store = YAML:Store.new('my_file.yml')

✅储存数据(过程三步走的第二步)

其格式与 hash 很相似,都需要一个 key 和一个响应的 value.
transaction是储存数据时需要执行的方法,用于 prevent other programs from writing to the file until the block exits.

store.transaction do
store["my key"] = "my value"
store["key two"] = "value two"
end

设置 object 的 ID

ID 是一个 object 的唯一标识,对于电影来说, 如果将 title 设为 ID, 那么就会产生一些缺陷:

  1. 由于有些电影 title 中存在”空格键“,因此在 URL 中不方便表示
  2. 可能存在 object 不同,但是两部电影的 title 相同的情况

因此, Numeric ID 是最佳选择.

设置步骤 & roots

  1. 在 Movie 这个 object 添加"id"这个属性.
  2. 在 lib 中添加 movie_store.rb ,编写一个 save 函数(其中用到 roots 这个属性)

roots: 一个 YAML:Store 的 instance 的属性,它能够将所有的 key 组合在一起,store 为一个 array.

代码如下:

class MovieStore

def initialize(file_name)
@store = YAML::Store.new(file_name)
end

def save(movie)
@store.transaction do
unless movie.id
highest_id = @store.roots.max || 0
movie.id = highest_id + 1
end
@store[movie.id] = movie
end
end

3⃣️ 将 .yml 中的字符串转变为 object

第一步: 取得 object 中的 values

使用 map 得到 .yml 中的 values

YAML::Store 的roots 方法返回的是各个 object 的 keys, 因此可以利用 map 这个 method 来得到其 values, map 的功能是:

  1. 将一个 array 中所有的元素都代入
  2. 返回一个新的 array, 它包含了 object 每个 key 对应的 value.

实现

    1. 在 moive_store.rb 中添加取得 values 的方法——all  def all
      @store.transaction do
      @store.roots.map {|id| @store[id]}
      end
      end 
    2. 在 app.rb 中,将 @movie 的相关内容改为 store.all

      get('/movies') do
      @movies = store.all
      erb :index
      end

第二步: Building HTML links to individual movies

parameter routes

格式:
get('/zipcode/:state')
功能:
Sinatra 中的用于 handle requests for multiple resources 的方法
需要注意:
其位置应该在所有 sinatra route 中 get, put 定义之后,因为如果在前面, 就会 override path 较短的 route

实现步骤

1 . 在 movie_store 中添加 find 方法

def find(id)
@store.transaction do
@store[id]
end
end

2 . 在 views 文件夹中新建展示详细内容的 show.erb 
3 . 在 app.rb 中添加 get('movies/:id') ,导入页面 erb :show

✅最后框架

HeadFirst Ruby 第十五章总结 Saving and loading data的更多相关文章

  1. HeadFirst Ruby 第十四章总结 Web apps: Serving HTML

    前言 这一章节主要讲了如何利用 Ruby 中的 Sinatra 这个 gem 来创建一个 Web app 的具体流程,其中的要点包括了: Sinatra, a third party library ...

  2. 15第十五章UDF用户自定义函数(转载)

    15第十五章UDF用户自定义函数 待补上 原文链接 本文由豆约翰博客备份专家远程一键发布

  3. 《Linux命令行与shell脚本编程大全》 第十五章 学习笔记

    第十五章:控制脚本 处理信号 重温Linux信号 信号 名称 描述 1 HUP 挂起 2 INT 中断 3 QUIT 结束运行 9 KILL 无条件终止 11 SEGV 段错误 15 TERM 尽可能 ...

  4. CSS3秘笈复习:十三章&十四章&十五章&十六章&十七章

    第十三章 1.在使用浮动时,源代码的顺序非常重要.浮动元素的HTML必须处在要包围它的元素的HTML之前. 2.清楚浮动: (1).在外围div的底部添加一个清除元素:clear属性可以防止元素包围浮 ...

  5. Gradle 1.12用户指南翻译——第四十五章. 应用程序插件

    本文由CSDN博客貌似掉线翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...

  6. Gradle 1.12 翻译——第十五章. 任务详述

    有关其他已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或访问:http://gradledoc.qiniudn.com ...

  7. Gradle 1.12用户指南翻译——第二十五章. Scala 插件

    其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...

  8. Gradle 1.12用户指南翻译——第三十五章. Sonar 插件

    本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...

  9. “全栈2019”Java多线程第三十五章:如何获取线程被等待的时间?

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

随机推荐

  1. centos6.9 svn提交更新到网站根目录

    一.首先创建网站根目录 ~] # mkdir -pv /export/home/cms/www_dyrs ~] # svn co svn://127.0.0.1/svn1 /export/home/c ...

  2. win7系统复制文件到u盘提示文件过大怎么办

    转载:https://www.xitmi.com/770.html 系统相信很多朋友都遇到过这种情况,在你拷贝文件到u盘时,u盘剩余空间明明很大,但是却复制不进去,电脑提示“对于目标文件系统 文件过大 ...

  3. QML的Window与ApplicationWindow

    ApplicationWindow需要导入QtQuick.Controls Window需要导入QtQuick.Window . 默认不可见,需要设置visible:true才可见. 主要区别就是Ap ...

  4. CSV是什么文件格式【转】

    本文转载自:https://blog.csdn.net/huyanping/article/details/6384687 CSV即Comma Separate Values,这种文件格式经常用来作为 ...

  5. HDU 6318 Swaps and Inversions(归并排序 || 树状数组)题解

    题意:一个逆序对罚钱x元,现在给你交换的机会,每交换任意相邻两个数花钱y,问你最少付多少钱 思路:最近在补之前还没过的题,发现了这道多校的题.显然,交换相邻两个数逆序对必然会变化+1或者-1,那我们肯 ...

  6. 【做题】zoj3649 Social Net——倍增

    这题是吴老师推荐的,于是我就去做了. 根据题意,在完成最大生成树后,对于树上从x到y的一条路径,求出最大的ck-cj(j<=k,ci为路径上第i个点的权值). 我一开始的想法是二分,记路径xy的 ...

  7. 【控制分片分配】控制Elasticsearch分片和副本的分配

    ES集群中索引可能由多个分片构成,并且每个分片可以拥有多个副本.通过将一个单独的索引分为多个分片,我们可以处理不能在一个单一的服务器上面运行的大型索引,简单的说就是索引的大小过大,导致效率问题.不能运 ...

  8. LOJ#2427. 「POI2010」珍珠项链 Beads

    题目地址 题目链接 题解 不会算复杂度真是致命,暴力枚举k每次计算是n/2+n/3+n/4+...+1的,用调和级数算是\(O(nlogn)\)的... 如果写哈希表的话能够\(O(nlogn)\), ...

  9. 案例2:用一条SQL查询出数学语文成绩都大于80分的学生姓名?

    方法1: 查出科目成绩有小于80分的学生姓名,再约束并去重学生不等于查出来的姓名 select distinct A.name from t_score A where A.name not in(s ...

  10. ASP.NET开发总结

    ASP.NET的界面可以是.aspx,会对应有一个.aspx.cs的逻辑处理文件,.aspx的所有控件对应着变量,变量名就是控件的ID. 为了代码编写方便起见,一般将数据库表的新增字段,放在最后. 日 ...