首先解释一下什么是rest,rest全称:Representational State Transfer, 中文意思是表述(编者注:通常译为表征)性状态转移。REST指的是一组架构约束条件和原则。" 如果一个架构符合REST的约束条件和原则,我们就称它为RESTful架构。(解释来自百度百科)
REST有主要有两个核心精神:1. 使用Resource来当做识别的资源,也就是使用一个URL网址来代表一个Resource 2. 同一个Resource则可以有不同的Representations格式变化。这一章的路由实现了Resource概念,而Representation则是用respond_to
方法来实现。
2.1资源与URI
REST全称是表述性状态转移,那究竟指的是什么的表述? 其实指的就是资源。任何事物,只要有被引用到的必要,它就是一个资源。
要让一个资源可以被识别,需要有个唯一标识,在Web中这个唯一标识就是URI(Uniform Resource Identifier)。URI既可以看成是资源的地址,也可以看成是资源的名称。
URI设计技巧:
2.2统一资源接口
2.3资源的表述
2.4资源的链接
2.5状态的转移
RESTful带给Rails最大的好处是:它帮助我们用一种比较标准化的方式来命名跟组织Controllers和Actions。在没有RESTful之前,我们上一章介绍了典型路由设计方式,也就是一个个指定Controller和Action,虽然十分地简便,但是却没有什么准则。同一个Action让不同的开发者设计,就很可能放在不同的Controller之下,更常见的是让一个Controller放太多不相关的Action,造成单一Controller过于庞大。
一般网页的运作原理是这样的:
1.使用者在浏览器里输入了某个网址,点击某个链接,都算HTTP请求(Request)
2.而浏览器回应之后,产生页面,或者重新导向,都算HTTP回应(Response)
这是最常用的两种类型/动作(Verb)的请求: GET / POST
GET: 输入网址,点击网址
POST: 送出表单
什么是HTTP method?在HTTP 1.1通讯协议中制定了九种动词(Verbs)来跟服务器沟通,分别是HEAD、GET、POST、PUT、DELETE、TRACE、OPTIONS、CONNECT、PATCH。其中最常见的就是GET和POST:GET用来读取数据,这个动作不应该造成任何数据变更。而POST用于送出数据,这个动作不会被快取。而因为HTML只能送出GET或透过窗体送出POST,Rails为了突破这个限制,在POST加上一个隐藏参数_method=PUT或_method=DELETE就可以当做PUT和DELETE请求了。
HTTP GET和其他动词最大的差别在于它被认为是一个纯读取、不会修改任何数据的操作,不像POST、PUT、DELETE会修改服务器上的数据。我们一般用浏览器GET网页,可以回上一页或重新整理,但是POST网页要重新整理时,浏览器会提示你是否要在执行一次,就是这个道理。
因为 CRUD 是常见的操作行为,但是大家实作的方式、与网址设计方式不一样。造成很多维护上的困扰。
后来就有人发明 RESTful 这个概念,希望用 HTTP 的动作 ( Verb)一起去封装 CRUD 的行为。所以又多加了两个动作:
接下来,我们就具体叭叭一下rails的RESTful
举例的功能名称:groups, 为了控制它的运作,我们会创建一个新的Controller文件叫做groups_controller.rb
设定路由routing,只有一行:
config/routes.rb resources :groups
有了这个,不管浏览器端想要什么样的请求request,Routing都会帮我导向正确的action去运作后续流程
终端里查rails routes,这一行命令会自动建立4个命名路由,搭配4个HTTP动词,对应7个Action。
7个action:index,show,new,create,edit,update,destroy
注:任何时候,删除的操作都是敏感的,逻辑合理的情况下,删除是丢失数据的根本原因,逻辑不合理的情况下,删除会导致不可逆转的bug。所以,一般删除都是假删除,我个人通常也会弃用destroy的概念,举个例子:做后台工具,运营同学的逻辑是,要把商品摆上去售卖,不想卖了的时候就把商品删除。其实他们队删除的理解是表面现象,我们完全可以用上下线的概念代替删除,所以加了一个上线时间的字段,他们所说的删除商品,就是把上线时间终止,而显示的时候,就会只显示在上线时间内的商品。总之,所有的删除操作,都可以用假删除代替。
上图也就是:
get '/groups' => "groups#index", as => "groups"
get 'group/:id' => "groups#show", as => "group"
get '/groups/new' => "groups#new", as => "new_group"
post '/groups' => "groups#create", as => "groups"
get '/groups/:id/edit' => "groups#edit", as => "edit_group"
put '/group/:id' => "group#update", as => "group"
delete '/groups/:id' => "groups#destroy", as => "group"
如果是Model中的程序,你可以在命令行下输入rails console,然后在Console中调用看看Model的方法看看正确与否。而除错Controller和Views一个简单的方法是你可以使用debug这个Helper方法,例如在app/views/events/show.html.erb中插入:
<%= debug(@event) %>
这样就会输出@event
这个值的详细内容。不过,更为常见的是使用Logger来记录信息到log/development.log里。
在Rails环境中,你可以直接使用logger或是Rails.logger
来拿到这个Logger对象,它有几个方法可以调用:
·logger.debug除错用的讯息,Production环境会忽略
·logger.info值得记录的一般讯息
·logger.warn值得记录的警告讯息
·logger.error错误讯息,但还不到网站无法执行的地步
·logger.fatal严重错误到网站无法执行的讯息
例如,你想要观察程序中变量@event的值,你可以插入以下程序到要观察的程序段落之中:
Rails.logger.debug("event: #{@event.inspect}")
开一个指令窗口执行tail-f log/development.log
来观察log文件,接着开浏览器跑实际跑过这段程序,你就会在log/development.log看到除错讯息。
在Production环境中,log/production.log会逐渐长大,可以使用logrotate 定期整理 Rails Log 文件。
或者
Rails也可以使用断点的除错方式,请编辑Gemfile里添加ruby-debug的gem:
# gem 'ruby-debug'
然后在要设定断点的地方调用debugger
方法,你的服务器程序或Console就会在这里停下来让你检查。不过,会必须要用到这招的情形不多就是了。