English 中文(简体)
Rails - RESTful Routing - Add a POST for Member i.e(tips/6)
原标题:

I m trying to create some nice RESTful structure for my app in rails but now I m stuck on a conception that unfortunately I m not sure if its correct, but if someone could help me on this it would be very well appreciated.

If noticed that for RESTful routes we have (the uncommented ones)

collection
    :index   =>  GET 
    :create  =>  POST 
   #:?       =>  PUT 
   #:?       =>  DELETE 

member 
    :show    =>  GET 
   #:?       =>  POST 
    :update  =>  PUT 
    :destroy =>  DELETE 

in this case I m only talking about base level action or the ones that occur directly inside i.e http://domain.com/screename/tips or http://domain.com/screename/tips/16

but at the same time I notice that there s no POST possibility for the members, anybody knows why?

What if I m trying to create a self contained item that clones itself with another onwer?

I m almost sure that this would be nicely generated by a POST method inside the member action, but unfortunately it looks like that there s no default methods on the map.resources on rails for this.

I tried something using :member, or :new but it doesn t work like this

 map.resources :tips, :path_prefix =>  :user , :member  => {:add => :post}

so this would be accessed inside http://domain.com/screename/tips/16/add and not http://domain.com/screename/tips/16.

So how would it be possible to create a "default" POST method for the member in a RESTful route?

I was thinking that maybe this isn t in there because it s not part of REST declaration, but as a quick search over it I found:

POST

for collections : Create a new entry in the collection where the ID is assigned automatically by the collection. The ID created is usually included as part of the data returned by this operation.

for members : Treats the addressed member as a collection in its own right and creates a new subordinate of it.

So this concept still the same if you think about the DELETE method or PUT for the collection. What if I want to delete all the collection instead just one member? or even replace them(PUT)?

So how could I create this specific methods that seems to be missing on map.resources?

That s it, I hope its easy to understand.

Cheers

最佳回答

The reason they aren t included by is that they re dangerous unless until secured. Member POST not so much as collection PUT/DELETE. The missing member POST is more a case of being made redundant by the default collection POST action.

If you still really want to add these extra default actions, the only way you re going to be able to do it, is it to rewrite bits of ActionController::Resources.

However this is not hard to do. Really you only need to rewrite two methods. Even then you don t have to rewrite them fully. The methods bits that you ll need to add to those methods don t really on complex processing of the arguments to achieve your goal. So you can get by with a simple pair of alias_method_chain.

Assuming I haven t made any errors, including the following will create your extra default routes as described below. But do so at your own risk.

module ActionController
  module Resources
    def map_member_actions_with_extra_restfulness(map, resource)
      map_member_actions_without_extra_restfulness(map, resource)
      route_path = "#{resource.shallow_name_prefix}#{resource.singular}"
      map_resource_routes(map, resource, :clone, resource.member_path, route_path, :post, :force_id => true)
    end

    alias_method_chain :map_member_actions, :extra_restfulness


    def map_default_collection_actions_with_extra_restfullness(map, resource)
      map_default_collection_actions_without_extra_restfullness(map,resource
      index_route_name = "#{resource.name_prefix}#{resource.plural}"

      if resource.uncountable?
        index_route_name << "_index"
      end

      map_resource_routes(map, resource, :rip, resource.path, index_route_name, :put)
      map_resource_routes(map, resource, :genocide, resource.path, index_route_name, :delete)
    end

    alias_method_chain :map_default_collection_actions, :extra_restfulness
  end
end

You ll have to mess around with generators to ensure that script/generate resource x will create meaningful methods for these new actions.

Now that we ve covered the practical part, lets talk about the theory. Part of the problem is coming up with words to describe the missing actions:

The member action described for POST in the question, although technically correct does not hold up when applied to ActionController and the underlying ActiveRecord. At best it is ambiguous, at, worst it s not possible. It makes sense for resources with a recursive nature (like trees,) or resources that have many of a different kind of resource. however this second case is ambiguous and already covered by Rails. Instead I chose clone for the collection POST. It made the most sense for default post on an existing record. Here are the rest of the default actions I decided on:

collection
    :index       =>  GET 
    :create      =>  POST 
    :rip         =>  PUT 
    :genocide    =>  DELETE 

member 
    :show    =>  GET 
    :clone   =>  POST 
    :update  =>  PUT 
    :destroy =>  DELETE 

I chose genocide for collection DELETE because it just sounded right. I chose rip for the collection PUT because that was the term a company I used to work for would describe the act of a customer replacing all of one vendor s gear with another s.

问题回答

I m not quite following, but to answer your last question there, you can add collection routes for update_multiple or destroy_multiple if you want to update or delete multiple records, rather than a single record one at a time.

I answered that question earlier today actually, you can find that here.

The reason that there s no POST to a particular member is because that member record already exists in the database, so the only thing you can do to it is GET (look at), PUT (update), or DELETE (destroy). POST is designed only for creating new records.

If you were trying to duplicate an existing member, you would want to GET the original member in a "duplicate" member action and POST to the resource root with its contents.

Please let me know if I m missing what you re asking.





相关问题
rails collection_select vs. select

collection_select and select Rails helpers: Which one should I use? I can t see a difference in both ways. Both helpers take a collection and generates options tags inside a select tag. Is there a ...

SSL slowness in EC2

We ve deployed our rails app to EC2. In our setup, we have two proxies on small instances behind round-robin DNS. These run nginx load balancers for a dynamically growing and shrinking farm of web ...

Auth-code with A-Za-z0-9 to use in an URL parameter

As part of a web application I need an auth-code to pass as a URL parameter. I am currently using (in Rails) : Digest::SHA1.hexdigest((object_id + rand(255)).to_s) Which provides long strings like : ...

RubyCAS-Client question: Rails

I ve installed RubyCAS-Client version 2.1.0 as a plugin within a rails app. It s working, but I d like to remove the ?ticket= in the url. Is this possible?

activerecord has_many :through find with one sql call

I have a these 3 models: class User < ActiveRecord::Base has_many :permissions, :dependent => :destroy has_many :roles, :through => :permissions end class Permission < ActiveRecord::...

Ordering a hash to xml: Rails

I m building an xml document from a hash. The xml attributes need to be in order. How can this be accomplished? hash.to_xml

Text Editor for Ruby-on-Rails

guys which text editor is good for Rubyonrails? i m using Windows and i was using E-Texteditor but its not free n its expired now can anyone plese tell me any free texteditor? n which one is best an ...

How to get SQL queries for each user where env is production

I’m developing an application dedicated to generate statistical reports, I would like that user after saving their stat report they save sql queries too. To do that I wrote the following module: ...

热门标签