- 浏览: 199471 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
ray_linn:
eval的速度也是慢得可以
Rails每周一题(十六): Evaluation in Ruby -
orcl_zhang:
>> Thing.my_class_eval do ...
Rails每周一题(十六): Evaluation in Ruby -
andyhu1007:
robbin 写道何况多进程rails都是每进程hold一个持 ...
线程安全的Rails -
robbin:
ruby本地的lib不是线程安全的,你多线程rails读取本地 ...
线程安全的Rails -
andyhu1007:
刚帮同事trouble shoot了一个问题:def upda ...
ActiveRecord的ORM问题域 Q&A
Rails其实很好懂,可视的源码和大量的注释,只看你有没有心去一窥究竟。今天就来看看貌似神秘的routes吧。
一个命令
首先,介绍一个rake命令。对于不了解routes定义规则的,或许看到routes.rb文件有点迷糊。不要紧,如果你想看看一个url到底对应了哪个controller以及action,就用rake routes展开所有的奥秘吧。
几多规则
routes的定义规则其实不多,让我们来一一分析下吧。不过要保持耐心。
分析routes.rb文件,首先得搞清楚,它的优先级是从上到下,谁先匹配谁先得。
1. 默认规则
# Install the default routes as the lowest priority. # Note: These default routes make all actions in every controller accessible via GET requests. You should # consider removing the them or commenting them out if you're using named routes and resources. map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format'
自定义的路由规则往往需要覆盖默认的路由规则,所以,rails的routes模板把默认路由规则放在文件的最下面,并且鼓励考虑用具名路由替换它们。
2. 无名规则
大家看到前面的map.connect,那么这个方法到底做了什么?
# Create an unnamed route with the provided +path+ and +options+. See # ActionController::Routing for an introduction to routes. def connect(path, options = {}) @set.add_route(path, options) end
可以看到,connect方法为我们生成了一个无名路由规则。
我们可以如此生成一个无名规则:
map.connect 'products/:id', :controller => 'catalog', :action => 'view'
3. 具名规则
为什么要有具名规则,主要是因为rails可以为具名规则生成一些url helper。关于routes的helper,待会儿再详细描述,先来看看具名规则吧。
map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'
如此,我们已经生成了一个名字叫做purchase的具名规则。
看看源代码
def named_route(name, path, options = {}) #:nodoc: @set.add_named_route(name, path, options) end
4. 单资源REST风格路由规则: map.resource
我们定义这样一个规则: map.resource :account
它会帮我们定义怎样的一个路由规则呢? 答案是一个遵循REST风格的路由规则,非常完美。
# maps these actions in the Accounts controller: class AccountsController < ActionController::Base # GET new_account_url def new # return an HTML form for describing the new account end # POST account_url def create # create an account end # GET account_url def show # find and return the account end # GET edit_account_url def edit # return an HTML form for editing the account end # PUT account_url def update # find and update the account end # DELETE account_url def destroy # delete the account end end
让我们用rake routes看看它为我们生成了怎样的路由。
account POST /account {:controller=>"accounts", :action=>"create"}
formatted_account POST /account.:format {:controller=>"accounts", :action=>"create"}
new_account GET /account/new {:controller=>"accounts", :action=>"new"}
formatted_new_account GET /account/new.:format {:controller=>"accounts", :action=>"new"}
edit_account GET /account/edit {:controller=>"accounts", :action=>"edit"}
formatted_edit_account GET /account/edit.:format {:controller=>"accounts", :action=>"edit"}
GET /account {:controller=>"accounts", :action=>"show"}
GET /account.:format {:controller=>"accounts", :action=>"show"}
PUT /account {:controller=>"accounts", :action=>"update"}
PUT /account.:format {:controller=>"accounts", :action=>"update"}
DELETE /account {:controller=>"accounts", :action=>"destroy"}
DELETE /account.:format {:controller=>"accounts", :action=>"destroy"}
5. 集合资源REST风格路由规则
我们定义一个这样的规则: map.resources :messages
# map.resources :messages # will map the following actions in the corresponding controller: class MessagesController < ActionController::Base # GET messages_url def index # return all messages end # GET new_message_url def new # return an HTML form for describing a new message end # POST messages_url def create # create a new message end # GET message_url(:id => 1) def show # find and return a specific message end # GET edit_message_url(:id => 1) def edit # return an HTML form for editing a specific message end # PUT message_url(:id => 1) def update # find and update a specific message end # DELETE message_url(:id => 1) def destroy # delete a specific message end end
messages GET /messages {:controller=>"messages", :action=>"index"}
formatted_messages GET /messages.:format {:controller=>"messages", :action=>"index"}
POST /messages {:controller=>"messages", :action=>"create"}
POST /messages.:format {:controller=>"messages", :action=>"create"}
new_user GET /messages/new {:controller=>"messages", :action=>"new"}
formatted_new_user GET /messages/new.:format {:controller=>"messages", :action=>"new"}
edit_user GET /messages/:id/edit {:controller=>"messages", :action=>"edit"}
formatted_edit_user GET /messages/:id/edit.:format {:controller=>"messages", :action=>"edit"}
user GET /messages/:id {:controller=>"messages", :action=>"show"}
formatted_user GET /messages/:id.:format {:controller=>"messages", :action=>"show"}
PUT /messages/:id {:controller=>"messages", :action=>"update"}
PUT /messages/:id.:format {:controller=>"messages", :action=>"update"}
DELETE /messages/:id {:controller=>"messages", :action=>"destroy"}
DELETE /messages/:id.:format {:controller=>"messages", :action=>"destroy"}
6. 嵌套规则
简单嵌套规则
map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller
用rake routes看看生成的路由规则,即可一目了然。
一个更加复杂的嵌套规则
map.resources :products do |products| products.resources :comments products.resources :sales, :collection => { :recent => :get } end
7. root
# You can have the root of your site routed with map.root -- just remember to delete public/index.html. map.root :controller => 'home'
root路由用于映射根目录。
8. namespace
我们还可以定义一个命名空间,如这样。
map.namespace :admin do |admin| # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb) admin.resources :products end
7. path_prefix, name_prefix等其他options
当想让不同的method访问同一个url时,对应到不同的controller或者action,可以如是:
map.signup '/signup', :controller => 'people', :action => 'new', :conditions => {:method => :get} map.signup '/signup', :controller => 'people', :action => 'create', :conditions => {:method => :post}
还是不再赘述了,这样的option很多,在不明白的时候,不如直接看源代码吧。
routes helpers
当我们定义了一个具名路由或者REST风格路由时,router helper会为我们生成一些帮助方法。
比如当我们定义了一个这样的路由时:
map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'
生成的helper方法有:
purchase_url(:id => 1) # http://test.url/products/1/purchase
purchase_path(:id => 1) # /products/1/purchase
hash_for_purchase_url(:id => 1) # {:controller=>"sessions", :action=>"new", :use_route=>:new_session, :only_path=>false}
hash_for_purchase_path(:id => 1) # {:controller=>"sessions", :action=>"new", :use_route=>:new_session, :only_path=>true}
delete & put
对delete和put method,现在大多数浏览器都不能处理,所以以post方法代替,并附上:method参数。
<% form_for :message, @message, :url => message_path(@message), :html => {:method => :put} do |f| %>
保持简单
最后有点感触,随着项目的进行,routes会变得越来越复杂,越来越难以看懂。所以,我们要遵循保持简单,尽量使用REST风格的原则。
评论
<div class="quote_div">
<p>Rails其实很好懂,可视的源码和大量的注释,只看你有没有心去一窥究竟。今天就来看看貌似神秘的routes吧。<br />
<br />
<strong>一个命令</strong>
<br />
<br />
首先,介绍一个rake命令。对于不了解routes定义规则的,或许看到routes.rb文件有点迷糊。不要紧,如果你想看看一个url到底对应了哪个controller以及action,就用rake routes展开所有的奥秘吧。<br />
<br />
<strong>几多规则<br />
<br />
</strong>
routes的定义规则其实不多,让我们来一一分析下吧。不过要保持耐心。<br />
<br />
分析routes.rb文件,首先得搞清楚,它的优先级是从上到下,谁先匹配谁先得。<br />
<br />
1. 默认规则</p>
<p> </p>
<pre name="code" class="ruby"> # Install the default routes as the lowest priority.
# Note: These default routes make all actions in every controller accessible via GET requests. You should
# consider removing the them or commenting them out if you're using named routes and resources.
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'</pre>
<p> </p>
<p>
自定义的路由规则往往需要覆盖默认的路由规则,所以,rails的routes模板把默认路由规则放在文件的最下面,并且鼓励考虑用具名路由替换它们。<br />
<br />
2. 无名规则<br />
<br />
大家看到前面的map.connect,那么这个方法到底做了什么?</p>
<pre name="code" class="ruby"> # Create an unnamed route with the provided +path+ and +options+. See
# ActionController::Routing for an introduction to routes.
def connect(path, options = {})
@set.add_route(path, options)
end</pre>
<p> </p>
<p>
可以看到,connect方法为我们生成了一个无名路由规则。<br />
<br />
我们可以如此生成一个无名规则:</p>
<pre name="code" class="ruby">map.connect 'products/:id', :controller => 'catalog', :action => 'view'</pre>
<p>
<br />
3. 具名规则<br />
<br />
为什么要有具名规则,主要是因为rails可以为具名规则生成一些url helper。关于routes的helper,待会儿再详细描述,先来看看具名规则吧。</p>
<p> </p>
<pre name="code" class="ruby">map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'</pre>
<p>
<br />
如此,我们已经生成了一个名字叫做purchase的具名规则。<br />
<br />
看看源代码</p>
<pre name="code" class="ruby">def named_route(name, path, options = {}) #:nodoc:
@set.add_named_route(name, path, options)
end</pre>
<p>
<br />
4. 单资源REST风格路由规则: map.resource<br />
<br />
我们定义这样一个规则: map.resource :account</p>
<p> </p>
<p> 它会帮我们定义怎样的一个路由规则呢? 答案是一个遵循REST风格的路由规则,非常完美。</p>
<p> </p>
<pre name="code" class="ruby"> # maps these actions in the Accounts controller:
class AccountsController < ActionController::Base
# GET new_account_url
def new
# return an HTML form for describing the new account
end
# POST account_url
def create
# create an account
end
# GET account_url
def show
# find and return the account
end
# GET edit_account_url
def edit
# return an HTML form for editing the account
end
# PUT account_url
def update
# find and update the account
end
# DELETE account_url
def destroy
# delete the account
end
end</pre>
<p> 让我们用rake routes看看它为我们生成了怎样的路由。</p>
<p> </p>
<p> account POST /account {:controller=>"accounts", :action=>"create"}<br />
formatted_account POST /account.:format {:controller=>"accounts", :action=>"create"}<br />
new_account GET /account/new {:controller=>"accounts", :action=>"new"}<br />
formatted_new_account GET /account/new.:format {:controller=>"accounts", :action=>"new"}<br />
edit_account GET /account/edit {:controller=>"accounts", :action=>"edit"}<br />
formatted_edit_account GET /account/edit.:format {:controller=>"accounts", :action=>"edit"}<br />
GET /account {:controller=>"accounts", :action=>"show"}<br />
GET /account.:format {:controller=>"accounts", :action=>"show"}<br />
PUT /account {:controller=>"accounts", :action=>"update"}<br />
PUT /account.:format {:controller=>"accounts", :action=>"update"}<br />
DELETE /account {:controller=>"accounts", :action=>"destroy"}<br />
DELETE /account.:format {:controller=>"accounts", :action=>"destroy"}<br />
<br />
<br />
5. 集合资源REST风格路由规则</p>
<p> </p>
<p> 我们定义一个这样的规则: map.resources :messages</p>
<p> </p>
<pre name="code" class="ruby"> # map.resources :messages
# will map the following actions in the corresponding controller:
class MessagesController < ActionController::Base
# GET messages_url
def index
# return all messages
end
# GET new_message_url
def new
# return an HTML form for describing a new message
end
# POST messages_url
def create
# create a new message
end
# GET message_url(:id => 1)
def show
# find and return a specific message
end
# GET edit_message_url(:id => 1)
def edit
# return an HTML form for editing a specific message
end
# PUT message_url(:id => 1)
def update
# find and update a specific message
end
# DELETE message_url(:id => 1)
def destroy
# delete a specific message
end
end</pre>
<p> </p>
<p> messages GET /messages {:controller=>"messages", :action=>"index"}<br />
formatted_messages GET /messages.:format {:controller=>"messages", :action=>"index"}<br />
POST /messages {:controller=>"messages", :action=>"create"}<br />
POST /messages.:format {:controller=>"messages", :action=>"create"}<br />
new_user GET /messages/new {:controller=>"messages", :action=>"new"}<br />
formatted_new_user GET /messages/new.:format {:controller=>"messages", :action=>"new"}<br />
edit_user GET /messages/:id/edit {:controller=>"messages", :action=>"edit"}<br />
formatted_edit_user GET /messages/:id/edit.:format {:controller=>"messages", :action=>"edit"}<br />
user GET /messages/:id {:controller=>"messages", :action=>"show"}<br />
formatted_user GET /messages/:id.:format {:controller=>"messages", :action=>"show"}<br />
PUT /messages/:id {:controller=>"messages", :action=>"update"}<br />
PUT /messages/:id.:format {:controller=>"messages", :action=>"update"}<br />
DELETE /messages/:id {:controller=>"messages", :action=>"destroy"}<br />
DELETE /messages/:id.:format {:controller=>"messages", :action=>"destroy"}</p>
<p>
<br />
<br />
6. 嵌套规则</p>
<p> </p>
<p> 简单嵌套规则</p>
<p> </p>
<pre name="code" class="ruby">map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller</pre>
<p> 用rake routes看看生成的路由规则,即可一目了然。</p>
<p><br />
一个更加复杂的嵌套规则</p>
<p> </p>
<pre name="code" class="ruby">map.resources :products do |products|
products.resources :comments
products.resources :sales, :collection => { :recent => :get }
end</pre>
<p>
7. root</p>
<pre name="code" class="ruby"># You can have the root of your site routed with map.root -- just remember to delete public/index.html.
map.root :controller => 'home' </pre>
<p> root路由用于映射根目录。<br />
<br />
8. namespace</p>
<p> </p>
<p> 我们还可以定义一个命名空间,如这样。</p>
<p> </p>
<p> </p>
<pre name="code" class="ruby">map.namespace :admin do |admin|
# Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb)
admin.resources :products
end</pre>
<p> </p>
<p>
7. path_prefix, name_prefix等其他options</p>
<p> </p>
<p> 还是不再赘述了,这样的option很多,在不明白的时候,不如直接看源代码吧。<br />
<br />
<br />
<strong>routes helpers<br />
</strong>
</p>
<p> </p>
<p> 当我们定义了一个具名路由或者REST风格路由时,router helper会为我们生成一些帮助方法。</p>
<p> </p>
<p> 比如当我们定义了一个这样的路由时:</p>
<p> </p>
<pre name="code" class="ruby">map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'</pre>
<p> </p>
<p> 生成的helper方法有:</p>
<p> </p>
<p> purchase_url(:id => 1) # http://test.url/products/1/purchase</p>
<p> purchase_path(:id => 1) # /products/1/purchase</p>
<p> hash_for_purchase_url(:id => 1) # {:controller=>"sessions", :action=>"new", :use_route=>:new_session,nly_path=>false}</p>
<p> hash_for_purchase_path(:id => 1) # {:controller=>"sessions", :action=>"new", :use_route=>:new_session,nly_path=>true}</p>
<p> </p>
<p><strong>
delete & put<br />
</strong>
</p>
<p> </p>
<p> 对delete和put method,现在大多数浏览器都不能处理,所以以post方法代替,并附上:method参数。</p>
<p> </p>
<p> </p>
<pre name="code" class="ruby"><% form_for :message, @message, :url => message_path(@message), :html => {:method => :put} do |f| %> </pre>
<p>
<strong>保持简单</strong>
</p>
<p> </p>
<p> 最后有点感触,随着项目的进行,routes会变得越来越复杂,越来越难以看懂。所以,我们要遵循保持简单,尽量使用REST风格的原则。</p>
</div>
<p> </p>
相关推荐
Rails::API 是 Rails 的精简版本,针对不需要使用完整 Rails 功能的开发者。 Rails::API 移除了 ActionView 和其他一些渲染功能,不关心Web前端的开发者可更容易、快速地开发应用程序,因此运行速度比正常的 Rails ...
在本篇内容中,我们将深入探讨如何利用Ruby on Rails(简称Rails)这一强大的Web应用程序框架来构建可伸缩且易于维护的RESTful API。Rails以其简洁优雅的语法、高效的开发速度以及良好的社区支持而闻名,这使得它...
Ruby on Rails,简称Rails,是一种基于Ruby语言的开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,旨在使Web开发过程更加高效、简洁。本篇将通过一个入门实例,深入探讨Rails的基本概念和核心...
Ruby on Rails,简称Rails,是基于Ruby语言的一个开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,旨在使Web开发过程更加高效、简洁。本压缩包中的"Ruby on Rails入门经典代码"提供了新手学习...
[适合] Rails :red_heart: Ansible [适合] Rails :red_heart: Ansible (有一点帮助) Rails部署 简单吧? 将应用程序放在服务器上。 捆绑宝石。 应用迁移。 重新启动服务。 Easy Rails部署 git push master ...
Rails 基本模板参考: : Ruby on Rails Gemfile:定义应用程序正在使用的库的文件bundle install:基于Gemfile,安装所有库每次修改 Gemfile 时都应该运行bundle install gem 是 Ruby 的库RubyGems.org 是一个查找和...
gem "rails-routes" 然后执行: $ bundle 或自己安装为: $ gem install rails-routes 用法 将这个gem添加到您的项目后,您可以在config/routes创建多个路由文件。 只要确保您用 # config/routes/v1.rb Rails . ...
RailsConsole 工具包 :wrench: :toolbox: 可配置的 Rails 控制台助手更快地查找记录,添加自定义助手,将您的控制台寿命提高 100%。安装将此行添加到应用程序的 Gemfile 中: gem 'rails_console_toolkit' 然后生成...
安装加 到Gemfile: gem 'rails_email_preview' , '~> 2.2.2' 添加一个初始化程序和路由: $ rails g rails_email_preview:install 在app / mailer_previews /中生成预览类和方法存根$ rails g rails_email_preview:...
标题 "Rails相关电子书汇总二" 提供的信息表明,这个压缩包包含的是一些关于Rails框架的高级主题的电子书籍资源。Rails是一个流行的开源Web应用框架,基于Ruby编程语言,它遵循模型-视图-控制器(MVC)架构模式,为...
webpack-rails, 将 web pack与你的Ruby on Rails 应用程序集成 不再维护webpack-rails 不再被维护。 有关详细信息,请参阅 #90. web pack-railsweb pack 为你提供了将 web pack集成到现有的Ruby on Rails 应用程序中...
标题 "rails-developer-scanning" 指向的是一个针对Rails开发者设计的自动化面试工具,旨在帮助面试官或招聘者快速有效地评估应聘者的Rails技能。这个工具名为 "jyaasa_interviewer",通过RubyGem安装,使得面试过程...
Rails :: Dom :: Testing 这个gem负责比较HTML DOM并断言Rails应用程序中存在DOM元素。 assert_dom_equal通过assert_dom_equal和assert_dom_not_equal进行比较。 元素通过assert_dom , assert_dom_encoded , ...
这个面试练习题可能是为了测试应聘者对于Rails应用的构建、自动化任务管理、测试驱动开发(TDD)以及文件组织结构的理解。让我们逐一探讨这些知识点。 首先,`Rakefile`是Ruby中的构建工具,类似于其他语言的...
4. **路由(Routes)**:Rails的路由系统将URL请求映射到特定的控制器动作,实现了URL和应用逻辑之间的解耦。 5. **辅助方法(Helper Methods)**:为视图提供便利的功能,如链接生成、样式辅助等。 6. **Scaffold...
路由 生成将所有以Rails命名的路由定义为javascript助手的javascript文件安装您的Rails Gemfile: gem "js-routes"设置跑: rake js:routes在app/javascript/packs/application.js中使路由全局可用: window ....
Rails :: Controller :: Testing 这个gem将assigns给控制器测试的内容以及assert_template带回assigns控制器和集成测试的内容。 这些方法已中。 安装 将此行添加到您的应用程序的Gemfile中: gem 'rails-...
rails_stack 食谱 TODO:在此处输入食谱说明。 例如,这本食谱使您最喜欢的早餐三明治。 要求 TODO:列出您的食谱要求。 确保包含本说明书对平台、库、其他说明书、软件包、操作系统等的任何要求。 例如 包裹 ...
Rails::Cache::Extended 这允许为记录集合生成自动过期的缓存键 安装 将此行添加到应用程序的 Gemfile 中: gem 'rails-cache-extended' 然后执行: $ bundle 或者自己安装: $ gem install rails-cache-...