3. REST, Resources, and Rails -

2016-04-07  本文已影响0人  介可能是只乌龟

3.9 RESTful Route Customisations

The techniques for doing this are useful when, for example, you’ve got more than one way of viewing a resource that might be described as showing. You can’t (or shouldn’t) use the show action itself for more than one such view. Instead, you need to think in terms of different perspectives on a resource, and create URLs for each one.

3.9.1 Etra Member Routes

For example, let’s say we want to make it possible to retract a bid. The basic nested route for bids looks like this:

resources :auctions do
  resources :bids
end

We’d like to have a retract action that shows a form (and perhaps does some screening for retractability). The retract isn’t the same as destroy; it’s more like a portal to destroy. It’s similar to edit, which serves as a form portal to update. Following the parallel with edit/update, we want a URL that looks like:

/auctions/3/bids/5/retract

and a helper method called retract_auction_bid_url. The way you achieve this is by specifying an extra member route for the bids.

resources :auctions do 
  resources :bids do
    member do
      get :retract
      post :retract
      # match :retract, via: [:get, :post]
    end 
  end
end

resources: auctions do 
  resources :bids do
    match :retract, via: [:get, :post], on: :member 
  end
end

3.9.2 Extra Collection Routes

You can use the same routing technique to add routes that conceptually apply to an entire collection of resources:

resources :auctions do 
  collection do
    match :terminate, via: [:get, :post] 
  end
end

In its shorter form:

resources :auctions do
  match :terminate, via: [:get, :post], on: :collection
end

This example will give you a terminate_auctions_path method, which will produce a URL mapping to the terminate action of the auctions controller. (A slightly bizarre example, perhaps, but the idea is that it would enable you to end all auctions at once.)

Thus you can fine-tune the routing behavior—even the RESTful routing behavior—of your application, so that you can arrange for special and specialized cases while still thinking in terms of resources.

3.9.3 Custom Action Names

Occasionally, you might want to deviate from the default naming convention for Rails RESTful routes. The :path_names option allows you to specify alternate name mappings. The example code shown changes the new and edit actions to Spanish-language equivalents.

resources :projects, path_names: {new: 'nuevo', edit: 'cambiar'}

3,9,4 Mapping to a Different Controller

You may use the :controller option to map a resource to a different controller than the one it would do so by default. This feature is occasionally useful for aliasing resources to a more natural controller name.

resources :photos, controller :"images"

3.9.5 Routes for New Resources

The routing system has a neat syntax for specifying routes that only apply to new resources, ones that haven’tbeen saved yet. You declare extra routes inside of a nested new block, like this:

resources :reports do 
  new do
    post :preview 
  end
end

The declaration above would result in the following route being defined.
preview_new_report POST /reports/new/preview(.:format) reports#preview

3.9.6 Considerations foro Extra Routes

Referring to extra member and collection actions, David has been quoted as saying, “If you’re writing so many additional methods that the repetition is beginning to bug you, you should revisit your intentions. You’re probably not being as RESTful as you could be.”

The last sentence is key. Adding extra actions corrupts the elegance of your overall RESTful application design, because it leads you away from finding all of the resources lurking in your domain.

Keeping in mind that real applications are more complicated than code examples in a reference book, let’s see what would happen if we had to model retractions strictly using resources. Rather than tacking a retract action onto the BidsController, we might feel compelled to introduce a retraction resource, associated with bids, and write a RetractionController to handle it.

resources :bids do
  resource :retraction 
end

`RetractionController` could now be in charge of everything having to do with retraction activities, rather than having that functionality mixed into `BidsController`. And if you think about it, something as weighty as bid retraction would eventually accumulate quite a bit of logic. Some would call breaking it out into its own controller proper separation of concerns or even just good object-orientation.
上一篇下一篇

猜你喜欢

热点阅读