- 浏览: 51683 次
- 性别:
- 来自: 青岛
文章分类
最新评论
REST, Resources, and Rails
Before REST came I (and pretty much everyone else) never really knew where to
put stuff.
—Jonas Nicklas on the Ruby on Rails mailing list
Routing and CRUD
当你在routes.rb里这么写的时候:
map.resources :auctions
你就已经创造了4个具名路由,实际上允许你访问7个action(index, create, show,
update, destroy, new, edit)。
/auctions GET
/auctions POST
HTTP方法不同,尽管url相同,仍然还是两个不同的东西。来看一个RESTFul的路由表,显示了helpers,paths,以及controller action的关系:
Helper
client_url(@client) - /clients/1 (show) ; /clients/1 (update); /clients/1 (destroy)
clients_url - /clients (index) ; /clients (create)
edit_client_url(@client) - /clients/1/edit (edit)
new_client_url - /clients/new (new)
当你生成一个URL的时候,你需要知道如何指定request方法,以防止你在GET /cients和POST /cients的时候触发了同一个action。看下面的一些规则:
默认的request 方法是GET
在form_for和form_tag方法被调用的时候,POST会被自动调用。
你也能通过具名路由专门指定你需要的(几乎最多的是PUT 和 DELETE)。
例子:
<%= link_to “Delete this auction”,:url => auction(@auction),:method => :delete %>
当调用update action的时候,需要指定PUT方法。
<% form_for “auction”, :url => auction(@auction),:html => { :method => :put } do |f| %>
The PUT and DELETE Cheat
浏 览器通常不会支持GET, POST以外的HTTP方法,为了发送PUT,DELETE请求,Rails做了一些小技巧。 PUT, DELETE请求,在Rest in Rails的上下文中,实际上是带有一个隐藏域“_method”方法的POST, 这个隐藏域来设置是‘put’还是‘delete’。
Singular and Plural RESTful Routes
一些Restful路由是单数的,一些是复数的,规则如下:
show,new, edit和destroy的路由是单数的,因为它们只为单独的资源工作。
其余action的路由都是复数,因为它们要处理相关资源的集合。
单数Restful路由需要一个参数,因为它需要指定你要操作资源的id:
item_url(@item) # show, update, or destroy, depending on HTTP verb
也可以用Hash的形式:
item_url(:id => @item)
你没必要一定要调用@item的id方法,Rails会帮你完成的。
The Special Pairs: new/create and edit/update
new / edit : 是用来得到form表单显示的。
create/update:是用来处理form提交的数据的。
new action,可以理解是得到一个单独的新的资源。但是HTTP动词GET,已经用在了show action上,所以new就必须有一个属于自己的名字。 这就是为什么我们需要这么使用:
<%= link_to “Create a new item”, new_item_path %>
edit action, 可以理解为给你一个不是正式的资源,是具有修改性质的的show资源,所以,这么用:
edit_item_url(@item)
Singular Resource Routes
map.resources也有map.resource这样的单数形式。
它一般被用在你应用上下文里仅出现一次的资源。看例子:
假如有个地址簿的应用,可能给每一个登陆用户一个地址簿,所以你可以写:
map.resource :address_book
你就会得到:
GET/PUT address_book_url,
GET edit_address_book_url,
PUT update_address_book_url.
注意以上这个例子所有的具名路由都是单数的。它是假定这个通信录在对于一个用户是唯一的。这里没有任何魔术,你必须登陆并且从数据库查找属于那个用户的address book, 路由只是给你提供个方便罢了。
Nested Resources
拿书里的竞标例子来说,每一次投标(bid)都关联着同一个auction。这意味着:
auction has_many bids
就像这样的:/auctions/3/bids/5
为什么不只是留下bids/5而跳过前面的auctions呢?
你可以从url上看出资源的信息。
这种url可以让你使用params[:auctions_id]来访问auction的id。
想创建嵌套资源,只需要在routes.rb里这么写:
map.resources :auctions do |auction|
auction.resources :bids
end
请注意里面的资源,是auction. 而不是map.
你可以使用,auction_bids_url, new_auction_bid_url等等。
<%= link_to “See all bids”, auction_bids_path(@auction) %>
这样你可以得到:/auctions/3/bids
你能通过params[:auction_id]找到@auction的id。
对于单独的bid资源(show,edit,destroy)你需要使用最少两个参数:
<%= link_to “Delete this bid”,
auction_bid_path(@auction, @bid), :method => :delete %>
你也可以使用hash的形式,但是大部分人不喜欢长代码:
auction_bid_path(:auction => @auction, :bid => @bid)
Setting :path_prefix Explicitly
设置前缀。
map.resources :auctions
map.resources :bids, :path_prefix => “auctions/:auction_id”
这个前缀和上面的嵌套资源实现的结果一样。但是和嵌套资源比这种方式更常用。
Setting :name_prefix Explicitly
可以控制你路由生成helper的方式。比如:
bid_path(@auction, @bid) 得到 /auctions/2/bids/5
bid_path(@bid) 得到 /bids/5
想实现这个功能,你只需要重写嵌套资源的name_prefix。
map.resources :auctions do |auction|
auction.resources :bids, :name_prefix => nil
end
你可能也想要这种helper方法:
bid_path(@auction, @bid) # /auctions/1/bids/1
bid_path(@person, @bid) # /people/1/bids/1
map.resources :auctions do |auction|
auction.resources :bids, :name_prefix => nil
end
map.resource :people do |people|
people.resources :bids, :name_prefix => nil # are you sure?
end
Specifying RESTful Controllers Explicitly
资源和controller的对应,是根据命名约定自动映射的。比如:
map.resources :auctions do |auction|
auction.resources :bids
end
对应的是AuctionsController和BidsController.你也可以自己指定controller:
map.resources :my_auctions, :controller => :auctions do |auction|
auction.resources :my_bids, :controller => :bids
end
All Together Now
现在我们知道了:name_prefix, :path_prefix, :controller三个选项。我们把它们一起来使用:
map.resources :auctions do |auction|
auction.resources :bids, :name_prefix => nil,
:controller => :auction_bids
end
map.resource :people do |people|
people.resources :bids, :name_prefix => nil,
:controller => :person_bids
end
AuctionBidsController和PersonBidsController会继承同一个父类BidsController。
class BidsController < ApplicationController
before_filter :load_parent
before_filter :load_bid
protected
def load_parent
# overriden in subclasses
end
def load_bid
@bids = @parent.bids
end
end
class AuctionBidsController < BidsController
protected
def load_parent
@parent = @auction = Auction.find(params[:auction_id])
end
end
class PersonBidsController < BidsController
protected
def load_parent
@parent = @person = Person.find(params[:person_id])
end
end
Deep Nesting?
map.resources :auctions do |auctions|
auctions.resources :bids do |bids|
bids.resources :comments
end
end
三层嵌套,这样可读性差。我们一般可以修改为:
map.resources :auctions do |auctions|
auctions.resources :bids
end
map.resources :bids do |bids|
bids.resources :comments
end
map.resources :comments
这样helper方法也容易去用:
auctions_path # /auctions
auctions_path(1) # /auctions/1
auction_bids_path(1) # /auctions/1/bids
bid_path(2) # /bids/2
bid_comments_path(3) # /bids/3/comments
comment_path(4) # /comments/4
RESTful Route Customizations
/auctions/3/bids/5/retract
map.resources :auctions do |a|
a.resources :bids, :member => { :retract => :get }
end
<%= link_to “Retract”, retract_bid_path(auction, bid) %>
也有:collection选项。
Formatted Named Routes
带格式的具名路由。
<%= link_to “XML version of this auction”,formatted_auction_path(@auction, “xml”) %>
会生成下列html:
<a href=”/auctions/1.xml”>XML version of this auction</a>
Reflecting on Rails Routing
You are in a maze of twisty little passages, all alike.
—Adventure (late 70s-era computer game)
Examining Routes in the Application Console
你可以在控制台检测你的路由系统。
Dumping Routes
$ ruby script/console
Loading development environment.
>> rs = ActionController::Routing::Routes
>> puts rs.routes
你可以看到全部定义好的路由:
GET /bids/ {:controller=>”bids”, :action=>”index”}
GET /bids.:format/ {:controller=>”bids”, :action=>”index”}
… …
Recognition and Generation in the Console
$ ./script/console
Loading development environment.
>> irb ActionController::Routing::Routes
>>
irb这个命名,会在console里面生成一个默认的self对象,self是指ActionController::Routing::Routes这个的对象。
你可以尝试以下命令:
>> generate(:controller => “bids”, :auction_id => 3, :action =>
“create”)
=> “/auctions/3/bids”
>> generate(:controller => “items”, :action => “item_year”, :year =>
1939)
=> “/item_year/1939”
>> generate(:controller => “items”, :action => “item_year”, :year =>
19393)
=> “/items/item_year?year=19393”
这个例子里year参数是4个数字,但是如果输入的不符合规范,则生成第二种url。
>> recognize_path(“/”)
=> {:controller=>”auctions”, :action=>”index”}
>> recognize_path(“/auctions”, :method => :get)
=> {:controller=>”auctions”, :action=>”index”}
>> recognize_path(“/auctions”, :method => :post)
=> {:controller=>”auctions”, :action=>”create”}
>> recognize_path(“/auctions/3/bids”, :method => :post)
=> {:controller=>”bids”, :action=>”create”, :auction_id=>”3”}
>> recognize_path(“/users/3/bids/1/retract”, :method => :get)
=> {:controller=>”bids”, :user_id=>”3”, :action=>”retract”, :id=>”1”}
>>exit
>>#<IRB::Irb: @context=#<IRB::Context:0×22f43f4>, @signal_status=:IN_EVAL, @scanner=#<RubyLex:0×22f3a6c>>
Named Routes in the Console
你也可以在控制台里执行命名路由。如下:
>> include ActionController::UrlWriter
=> Object
>> default_url_options[:host] = “example.com”
=> “example.com”
>>
>> auction_url(1)
=> “http://example.com/auctions/1”
>> formatted_auction_url(1,”xml”)
=> “http://example.com/auctions/1.xml”
>> formatted_auctions_url(“xml”)
=> “http://example.com/auctions.xml”
本文出自 “{ :Alex Space => ” Ruby Notes ” }” 博客,请务必保留此出处http://blackanger.blog.51cto.com/140924/122055
发表评论
-
client_side_validations
2011-12-27 16:31 1148client_side_validations是一个 ... -
alias, alias_method和alias_method_chain
2011-12-26 16:34 875本文介绍Ruby里的几个关键字。 1. alias ... -
Ubuntu上Apache+Passenger部署实践
2011-12-07 11:39 1369http://hi.baidu.com/hackerbase/ ... -
用vim 开发rails
2011-12-05 19:11 59之前一直使用netbeans开发rails,看到同事们 都 ... -
gem 降级
2011-10-09 17:21 1967gem uninstall rubygems- ... -
render vs redirect
2011-08-15 15:53 984render和redirect的区别在于: rende ... -
ruby 正则匹配非站内链接
2011-08-01 16:48 960def has_href_not_XXX?(content ... -
ruby 中的 方法调用作用域
2011-04-27 16:09 1330因此private和protected的在ruby当前和Jav ... -
rails 学习小结
2011-04-25 17:25 1028具名域 和 匿名域 ,rails无法处 ... -
find ---:readonly
2011-04-25 17:02 723如果:readonly 被设为 true 则不能将 find ... -
主键与ID
2011-04-25 16:43 877默认的主键为ID,我们可以如下来修改主键, ... -
rails Boolean型属性
2011-04-25 16:28 1526ruby中 对真值的定义 非常简单 除了nil和fals ... -
REST
2011-04-13 15:58 715http://hi.baidu.com/magiclin/bl ... -
ruby & rails 安装
2011-04-09 00:11 781ry1.8.7安装: 在终端执行: ... -
运用ActiveRecord
2011-04-08 16:46 92001.创建新实例 #01.1 a=Article.new ... -
刚学的一个activeRecord语句
2011-04-08 16:39 858学习rails两个礼拜了,加油加油 Person.find( ... -
将find出来的对象数组 组装成 字符串数组
2011-04-08 16:29 880user=User.find(:all,:select=& ... -
Rails Form helpers
2011-03-31 21:23 1340文章转自:http://yuan.iteye. ...
相关推荐
gem "rails-routes" 然后执行: $ bundle 或自己安装为: $ gem install rails-routes 用法 将这个gem添加到您的项目后,您可以在config/routes创建多个路由文件。 只要确保您用 # config/routes/v1.rb Rails . ...
《Rails 101 入门电子书》是一本非常适合初学者直接入门的书籍,它由xdite编写并出版于2014年6月10日。本书主要针对的是希望学习Ruby on Rails框架的读者,特别是那些想要从零开始掌握这项技术的新手。 #### 二、...
介绍rails框架,版本是rails2点几的,不过思路差不多,具体区别可以去看官网
本篇将通过一个入门实例,深入探讨Rails的基本概念和核心特性。 首先,让我们了解一下Rails的主要组件: 1. **Model**:模型是应用程序中的数据层,它与数据库交互,负责业务逻辑和数据验证。在Rails中,我们通常...
本书《Component-Based Rails Applications》主要介绍了如何使用Rails引擎(Rails Engine)进行基于组件的Rails应用开发,以及如何对应用程序的大型模块进行拆分和模块化。以下是书中一些核心知识点的详细说明: 1....
- **示例**:例如,在博客系统中,一篇文章可以有多个评论,这就是典型的“一对多”关系。 #### 四、查询 - **方法**:使用Active Record的方法来进行数据库查询,如`find`、`where`、`joins`等。 - **优化**:...
《Rails101_by_rails4.0》是一本专注于Rails 4.0.0版本和Ruby 2.0.0版本的自学教程书籍,它定位于中文读者,旨在成为学习Rails框架的参考教材。Rails(Ruby on Rails)是一个采用Ruby语言编写的开源Web应用框架,它...
本教程首先会介绍Rails的安装过程,包括Ruby环境的搭建、Rails框架的获取和配置,确保读者能够顺利创建第一个Rails项目。在项目创建环节,会讲解如何使用`rails new`命令来初始化一个新的应用,并解释各部分文件和...
本章详细介绍Rails数据持久化技术ActiveRecord的使用,包括ORM与ActiveRecord的简介、建立数据表的映射、执行动态查询、插入数据、删除数据、表之间的关联,以及数据有效性验证等。 第11章 MVC的控制器层。本章...
此压缩包中的"rubyonrails21-cn.pdf"可能是《Ruby on Rails 2.1中文版》这本书的电子版,这本书详细介绍了Rails 2.1版本的特性、使用方法以及开发流程。 Rails框架的核心概念包括: 1. **ActiveRecord**:这是...
Ruby on Rails,通常简称为Rails,是一个基于Ruby编程语言的开源Web应用框架,遵循MVC(Model-View-Controller)架构模式。这个“Rails项目源代码”是一个使用Rails构建的图片分享网站的完整源代码,它揭示了如何...
《Rails 101S》是一本为Ruby on Rails初学者准备的手册,旨在帮助新手快速入门并掌握基本的开发技能。本手册将从最基础的概念入手,逐步深入到实际项目的构建过程。 #### HelloWorld: 快速体验Ruby on Rails - **...
将 Grape API 路由装入 Rails 后,Grape API 路由通常不会打印在rake routes或/rails/info/routes 。 这个 gem 将 Grape 的路由打印功能添加到 Rails 中。 用法 将此行添加到您的Gemfile gem 'grape-rails-routes...
Rails指南中文版是针对Ruby on Rails框架的一份详尽教程,旨在帮助开发者深入理解并熟练掌握这个强大的Web应用开发工具。Ruby on Rails(简称Rails)是一个基于Ruby语言的开源Web应用框架,它遵循MVC(Model-View-...
- **routes.rb文件**:这是Rails应用程序中配置路由规则的地方,通过编写不同的路由规则可以实现复杂的应用逻辑。 - **命名路由**:允许开发者通过名字引用路由,使得代码更具可读性,并且可以在路由规则改变时自动...
MVC是Rails的核心架构之一,这一章节将详细介绍这三个组件的作用和相互关系。模型负责与数据库交互,管理数据;视图用于展示数据给用户;控制器则处理用户请求,协调模型和视图之间的操作。了解并正确运用MVC模式是...
**Ruby on Rails(RoR)** 是一个基于Ruby语言的开源Web开发框架,它遵循MVC(模型-视图-控制器)架构模式,用于构建高效、简洁和可维护的Web应用。RailsGuides中的"blog"程序是一个典型的入门级示例,旨在帮助初学...