`
ddl1st
  • 浏览: 98961 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Rails3 routes

 
阅读更多

Stop! I’d like to tell you something important, but it may be a bit shocking, so you should probably have a seat. Here goes: everything you knew about working with routes in Rails 2… is history! With Rails 3, you’ve got to roll up your sleeves, unlearn what you learned, and route the new way around. And this time, it’s faster, cleaner and a lot more Ruby-like.

In this post, we’ll walk through the underpinnings of Routes in Rails 3. They’ve been rewritten—for good reason—and after we get through the explanation, I’m confident you’ll agree.

Let’s start by looking at some code; here’s the new DSL, in its full glory:

resources :products do
  resource :category
 
  member do
    post :short
  end
 
  collection do
    get :long
  end
end
 
match "/posts/github" => redirect("http://github.com/rails.atom")

Now check out the old way of doing it:

map.resources :products, :member => {:short => :post}, :collection => {:long => :get} do |products|
  products.resource :category
end

As you can see, the example from Rails 3 is much cleaner and more Rubyish. So let’s jump right in and walk through a quick overview of how you’d define different types of routes in Rails 3.

Default Route

The default route in Rails 3, match '/:controller(/:action(/:id))', is much more explicit, as the parenthesis denote optional parameters.

Regular Routes

Rather than defining different keys for controller and action, you just have catalog#view, which is pretty awesome.

match 'products/:id', :to => 'catalog#view'

In Rails 2, you would’ve done:

map.connect 'products/:id', :controller => 'products', :action => 'view'

Named Routes

Named Routes generate helpers like posts_url and posts_path, rather than manually defining the hash to action and controller in helper methods like link_to:

match 'logout', :to => 'sessions#destroy', :as => "logout"

The key :as specifies a name to generate helpers. In Rails 2, you would have done:

map.logout '/logout', :controller => 'sessions', :action => 'destroy'

Empty Route

The root of the web site is the empty route. Whereas Rails 2 added a nice shortcut to it, Rails 3 simplifies things even further:

# Rails 3
root :to => 'welcome#show'
 
# Rails 2
map.root :controller => "welcome", :action => 'show'

Shorthands

The revamped routes in Rails 3 sport some nice shortcuts to commonly used routes. There are two types of shorthands. First, the :to shorthand allows you to skip the :to key and directly designate the route to the matcher:

match "/account" => "account#index"
match "/info" => "projects#info", :as => "info"

Second, the match shorthand allows you to define a path and controller with its action at the same time:

match "account/overview"
 
# identical to
 
match "account/overview", :to => "account#overview"

Verb Routes

While you can limit a route to an HTTP request through :via, it’s a nice added convenience to have Verb routes. Adding sugar on top, you can even use shorthands with them:

get "account/overview"
 
# identical to
 
match "account/overview", :to => "account#overview", :via => "get"

Keys

The match method (as well as the verb shorthands) take a number of optional keys.

:as

The :as key names the route. You can then use named route helpers wherever url_for is available (such as controllers, tests, and mailers). Resource routes (using the resources helper) automatically create named routes, as in Rails 2.3.

match "account/overview/:id", :as => "overview"
 
# in your controller
 
overview_path(12) #=> "/account/overview/12"

:via

Allows you to specify a set of verbs, so only those HTTP requests are accepted for a route.

match "account/setup", :via => [:get, :post]

Rack

Rack is a sweet interface to web servers that provides unified API to Ruby frameworks. Most if not all Ruby frameworks are built on top of Rack these days. The recent built-in support for Rack means your application is not bound to being Rails specific. You can have parts of your application handled by any Rack supported framework, be it Sinatra, Cramp or something else. You can skip the Rails stack altogether and pass on the request to a Rack app.

Here’s an example of a Sinatra app:

class HomeApp < Sinatra::Base
  get "/" do
    "Hello World!"
  end
end
 
Rizwan::Application.routes do
  match "/home", :to => HomeApp
end

And here’s an example of a Rack app:

match "/foo", :to => proc {|env| [200, {}, ["Hello world"]] }
 
match 'rocketeer.js' => ::TestRoutingMapper::RocketeerApp
 
RocketeerApp = lambda { |env|
  [200, {"Content-Type" => "text/html"}, ["javascripts"]]
}

Resourceful Routes

Since Rails 1.2, resourceful routes have been the preferred way to use the router. Recognizing this fact, the Rails core team has added some nice improvements. Take a look at this typical RESTful route in Rails 3:

resources :products

This would generate all the neat helpers we have come to love and would also route the URLs accordingly. Just like before, you can also add multiple resources in a single line:

resources :products, :posts, :categories

More RESTful Actions

As you know, you’re not limited to the seven actions that RESTful architecture provides, but can also define more actions in a resource. Having said that, you might want to keep an eye open if you’re defining lots of actions in a single resource, as they can be turned into separate resources.

We can add RESTful actions to this resource in a couple of ways. Here’s a few collectionRESTful actions inside a block:

resources :products do
  collection do
    get  :sold
    post :on_offer
  end
end

And take a look at this inline member RESTful action:

resources :products do
  get :sold, :on => :member
end

Not only that, but you can also redefine to extend the scope of the default seven RESTful actions:

resources :session do
  collection do
    get :create
  end
end

create actions, which usually only accepts POST requests, can now accept GET requests as well:

resource :session do
  get :create
end

Nested Resources

In Rails 2, nested resources were defined by a block or by using a :has_many or :has_onekey. Both of these have been superseded by a block, giving them a more Rubyish interface to defining associated resources.

Here’s a route for a project that has many tasks and people:

resources :projects do
  resources :tasks, :people
end

Namespaced Resources

These are especially useful when defining resources in a folder; it doesn’t get much cleaner than this:

namespace :admin do
  resources :projects
end

Renaming Resources

You can also rename resources through the :as key. This code uses :as in resourceful routes to change the products path to devices:

namespace :forum do
  resources :products, :as => 'devices' do
    resources :questions
  end
end

Restricting Resources

Resources can be restricted to only specified actions.

resources :posts, :except => [:index]
 
resources :posts, :only => [:new, :create]

Altering Path Names

You can define a different path name for a particular REST action. This helps you customize your RESTful routes. This code will route /projects/1/cambiar to the edit action.

resources :projects, :path_names => { :edit => 'cambiar' }

The Redirect Method

The newly added redirect method in Rails 3 provides a level of convenience not present before. For example, it can redirect to any path given and eventually, can also pass on to a full-blown URI, something previously accomplished by Rails plugins like redirect_routing.

Moreover, the redirect method also introduces generic actions. Unique to Rails 3, generic actions are a simple way to provide the same action to complex paths, depending on what’s passed to redirect.

This code will redirect /foo/1 to /bar/1s:

match "/foo/:id", :to => redirect("/bar/%{id}s")

This code will redirect /account/proc/john to /johns.

match 'account/proc/:name', :to => redirect {|params| "/#{params[:name].pluralize}" }

Note that redirect cannot be used in a block as opposed to other constraints and scopes.

The Constraints Method

Constraints allow you to specify requirements for path segments in routes. Besides that, they also allow you to use a handful of methods to verify whether or not something matches a given criteria. Like a route that checks if the request is AJAX or not, for example.

In this code, we’re using a regular expression, and the route has been restricted to only allow one digit IDs to pass through:

match "/posts/show/:id", :to => "posts#index", :constraints => {:id => /\d/}

Scope

When the scope method is passed along a symbol, it assumes the symbol is a controller. When the argument is a string, the scope method prepends that string to the beginning of the path.

Scope can also have path_segments, which can be constrained, giving us greater flexibility in routes.

controller :articles do
  scope '/articles', :name_prefix => 'article' do
    scope :path => '/:title', :title => /[a-z]+/, :as => :with_title do
      match '/:id', :to => :with_id
    end
  end
end
 
scope :posts, :name_prefix => "posts" do
  match "/:action", :as => "action"
end
 
scope ':access_token', :constraints => { :access_token => /\w{5,5}/ } do # See constraint here
  resources :rooms
end

As you can see, when scope is given a string as its argument, it prepends to the path, something that was accomplished through path_prefix in Rails 2. name_prefix is essentially the same as before.

Optional Segments

Unlike all the previous versions of Rails, path segments can now be optional in routes. Optional segments don’t necessarily have to be path segments, which are passed as parameters to the action. The default route is a good example of optional segments in use. Here, both/posts/new and /posts will be redirected to the create action in posts controller, but/posts/edit will not work:

match 'posts(/new)', :to => 'posts#create'

This is an optional path scope that allows to have a prepended path before a resource:

scope '(:locale)', :locale => /en|pl/ do
  resources :descriptions
end

Pervasive Blocks

As evident from the examples, routes in Rails 3 exhibit pervasive blocks for almost all the methods you’d normally want to pass a block to, helping you achieve DRY in routes.rb.

controller :posts do
  match 'export', :to => :new, :as => :export_request
  match '/:action'
end

Right now, most Rails developers wouldn’t use all of these methods, but when the need arises—when you need to define more complex routes—you might appreciate having the above information handy. You don’t need to use a plugin or a hack when you know it’s built right in. With Rails 3, Routes rock at a whole new level.

Questions and comments welcome!

文章来源: http://www.engineyard.com/blog/2010/the-lowdown-on-routes-in-rails-3/

分享到:
评论

相关推荐

    rails-routes:在Rails应用程序上启用configroutes * .rb

    gem "rails-routes" 然后执行: $ bundle 或自己安装为: $ gem install rails-routes 用法 将这个gem添加到您的项目后,您可以在config/routes创建多个路由文件。 只要确保您用 # config/routes/v1.rb Rails . ...

    grape-rails-routes:为 Grape with Rails 添加路由打印

    将 Grape API 路由装入 Rails 后,Grape API 路由通常不会打印在rake routes或/rails/info/routes 。 这个 gem 将 Grape 的路由打印功能添加到 Rails 中。 用法 将此行添加到您的Gemfile gem 'grape-rails-routes...

    ember-cli-rails-routes

    ember-cli-rails-routes 安装 将此添加到您的Gemfile并bundle install gem 'ember-cli-rails-routes' 设置 Rails应用 在您的routes.rb文件中: ember_app :foo , scope : :app , path : 'frontend' 这反映了...

    atom-rails-routes:Rails路线的Autocomplete +和hy​​perclick提供程序

    Atom Rails Routes是一款专门为Ruby on Rails开发者设计的Atom编辑器插件。它提供了强大的自动化功能,以提高开发效率,特别是对于处理Rails应用中的路由工作。这款插件由两个主要组件组成:Autocomplete Provider...

    Ruby Rails 3 Linda

    在“Ruby Rails 3 Linda”这一主题中,我们将会深入探讨Rails 3版本的相关知识点。 1. **安装与设置**:首先,学习如何在本地环境中安装Ruby、RubyGems和Rails。Ruby版本管理器如RVM(Ruby Version Manager)或...

    Rails 101 入门电子书

    #### 十、练习作业3-为Group与Post加入使用者机制 - **目标**: - 添加用户身份验证。 - **实现过程**: - 使用Devise gem。 - 实现登录/注册功能。 - 关联Group和User。 - **安全措施**: - 加入权限控制。 - ...

    Flexible Rails: Flex3 on Rails2

    2. **路由匹配**:Web服务器将请求传递给Rails中的路由代码,根据`config/routes.rb`中定义的路由规则触发相应的控制器方法。 3. **控制器逻辑**:控制器方法被调用后,会与各种ActiveRecord模型进行交互,这些模型...

    Rails项目源代码

    `config/routes.rb`文件定义了所有路由规则,包括资源路由、命名路由和自定义路由。 6. **视图模板**: 视图使用ERB(Embedded Ruby)或更现代的Haml、Slim等模板语言,结合HTML来渲染用户界面。图片的展示、上传...

    ember-cli-rails-routes-addon

    Ember CLI Rails Routes插件 这是ember-cli-rails路由层的Ember CLI附加部分。 这个插件有两个工作: 在资产URL前面加上Rails查找Ember应用程序所需的路径 根据Rails挂载点设置Ember应用程序的rootURL 目标: ...

    rails指南 中文版

    4. **Routes**:Rails的路由系统负责将HTTP请求映射到相应的控制器动作。通过配置routes.rb文件,开发者可以定义资源、命名路由等,使URL管理更加灵活。 5. **Gemfile与Bundler**:Rails项目通常使用Gemfile来管理...

    Ruby on Rails入门例子

    - **路由(Routes)**:Rails的路由系统将URL映射到特定的控制器动作,定义了应用的导航结构。在`config/routes.rb`文件中配置路由规则。 - **生成器(Generators)**:Rails提供了强大的生成器工具,可以自动生成...

    Rails相关电子书汇总

    4. **路由(Routes)**:Rails的路由系统将URL请求映射到特定的控制器动作,实现了URL和应用逻辑之间的解耦。 5. **辅助方法(Helper Methods)**:为视图提供便利的功能,如链接生成、样式辅助等。 6. **Scaffold...

    component base rails applications

    3. 组件化与Rails基础: - 本书假设读者已经掌握Ruby和Rails基础知识,包括Rails 2等基础知识,不包含这些内容的详细介绍。 4. 开发组件化的Rails应用: - 学习如何开始编写基于组件的Rails应用程序。 - 探讨了...

    Ruby on Rails Guides v2 - Ruby on Rails 4.2.5

    - **配置**:在`config/routes.rb`文件中添加新的路由规则,例如`get 'new_route' =&gt; 'controller#action'`。 - **效果**:这将在应用中增加一个新的URL路径,指向指定控制器的动作。 #### 七、渲染视图 - **方法*...

    rails 项目起步示例

    - **Routes**:Rails的路由系统将URL映射到控制器的行动上,定义了应用程序的导航路径。 - **Scaffolding**:快速生成基本的CRUD(创建、读取、更新、删除)功能的工具,对初学者非常有用。 - **Gemfile**:定义...

    ruby rails demo

    (2)安装Rails3 gem install rails (3)安装sqlite3 gem install sqlite3-ruby 安装sqlite3时候会提示你从链接中下载sqlite3.dll到ruby安装目录的bin文件夹下! (4)安装mysql gem install mysql2 创建项目: rails ...

    Rails上的API:使用Rails构建REST APIAPIs on Rails: Building REST APIs with Rails

    2. **设置路由**:使用Rails的`routes.rb`文件定义对应的路由规则,例如: ```ruby namespace :api do resources :users, only: [:index, :show, :create, :update, :destroy] end ``` 3. **实现控制器**:针对...

    Ruby+for+Rails

    Rails的路由系统将URL映射到控制器的动作上,定义在`config/routes.rb`文件中。例如,`resources :books`会生成CRUD(创建、读取、更新、删除)相关的路由。 8. **ActiveRecord** Rails的ORM(对象关系映射)层,...

Global site tag (gtag.js) - Google Analytics