Ruby on Rails-2.0.2 source code analysis (3)-Resource

Source: Internet
Author: User
Tags ruby on rails
  • Restful embodiment ---- Resource

Of course, it seems quite narrow to put restful and resource together. In rails, actioncontroller: Resources abstracts resources in rest. Here, I will not talk about the concept of rest, A huge amount of online information. Let's take a look at how resource is used in rails to easily and easily complete restful applications.

Resources. Rb

Source code path:/actionpack-2.0.2/lib/action_controller/resources. Rb
First of all, we do not need to look at the resource in depth, you can understand it as, when you define the following resource in routes. RB:

Map. Resources: Products
Rails will automatically generate a large number of named route for us. These route correspond to the action in the corresponding controller through HTTP verb. Of course, many helper methods are also generated. See the following table:

Named route Helpers
Product
product_url, hash_for_product_url,product_path, hash_for_product_path
new_product
new_product_url, hash_for_new_product_url,new_product_path, hash_for_new_product_path
edit_product
edit_product_url, hash_for_edit_product_url,edit_product_path, hash_for_edit_product_path
... ...

From this point of view, you can think of resource as a vest of many related named route.

The entire process is relatively intuitive. rails uses resource to generate various route step by step. Next, let's take a look at how the core code completes these functions. First, the following resource may be defined in routes. RB:

Ruby code
  1. Actioncontroller: routing: routes. DrawDo| Map |
  2. Map. Resources: Products
  3. ...
  4. End
ActionController::Routing::Routes.draw do |map|  map.resources :products  ...end

The resources method is defined in the module actioncontroller: resources, and then enters the Mapper class through Mixin. Let's first take a look at this method:

Ruby code
  1. DefResources (* entities, & Block)
  2. Options = Entities. extract_options!
  3. Entities.Each{| Entity | map_resource (entity, options. dup, & Block )}
  4. End
def resources(*entities, &block)  options = entities.extract_options!  entities.each { |entity| map_resource(entity, options.dup, &block) }end

It is easy to separate entities and options from parameters, and then perform the map_resource operation for each entity. Let's continue and see the true face of the map_resource method:

 

Ruby code
  1. DefMap_resource (entities, options ={}, & Block)
  2. Resource = resource.New(Entities, options)
  3. With_options: controller => resource. ControllerDo| Map |
  4. Map_collection_actions (MAP, resource)
  5. Map_default_collection_actions (MAP, resource)
  6. Map_new_actions (MAP, resource)
  7. Map_member_actions (MAP, resource)
  8. Map_associations (resource, options)
  9. IfBlock_given?
  10. With_options (: path_prefix => resource. nesting_path_prefix,: name_prefix => resource. nesting_name_prefix,: namespace => options [: namespace], & Block)
  11. End
  12. End
  13. End
def map_resource(entities, options = {}, &block)  resource = Resource.new(entities, options)  with_options :controller => resource.controller do |map|    map_collection_actions(map, resource)    map_default_collection_actions(map, resource)    map_new_actions(map, resource)    map_member_actions(map, resource)    map_associations(resource, options)    if block_given?      with_options(:path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix, :namespace => options[:namespace], &block)    end  endend

With entity and options, what are you waiting? Generate our resource object immediately. The resource object encapsulates the collection method, member method, new method, path prefix, name prefix, single/plural representation, and option related to the resource. The resource object is generated by parsing the corresponding attributes of the object from options and saving them. The code is simple and will not be pasted here.
Now, the resource object is available. We can see from the code above. Next, we will handle the named route related to this resource. The specific processing logic is similar. Here, map_member_actions (MAP, resource) is used as a signal. Interested students can view the source code on their own.

 

Ruby code
  1. DefMap_member_actions (MAP, resource)
  2. Resource. member_methods.Each Do| Method, actions |
  3. Actions.Each Do| Action |
  4. Action_options = action_options_for (action, resource, method)
  5. Map. named_route ("# {Action }_# {resource. name_prefix} # {resource. singular} "," # {resource. member_path} # {resource. action_separator }#{ action} ", action_options)
  6. Map. named_route ("Formatted _ # {action} _ # {resource. name_prefix} # {resource. singular} "," # {resource. member_path} # {resource. action_separator }#{ action }.: Format ", action_options)
  7. End
  8. End
  9. Show_action_options = action_options_for ("show", resource)
  10. Map. named_route ("# {resource. name_prefix} # {resource. Singular}", resource. member_path, show_action_options)
  11. Map. named_route ("Formatted _ # {resource. name_prefix} # {resource. Singular}", "# {resource. member_path}.: Format", show_action_options)
  12. Update_action_options = action_options_for ("Update", resource)
  13. Map. Connect (resource. member_path, update_action_options)
  14. Map. Connect ("# {resource. member_path}.: Format", update_action_options)
  15. Destroy_action_options = action_options_for ("Destroy", resource)
  16. Map. Connect (resource. member_path, destroy_action_options)
  17. Map. Connect ("# {resource. member_path}.: Format", destroy_action_options)
  18. End
def map_member_actions(map, resource)  resource.member_methods.each do |method, actions|    actions.each do |action|      action_options = action_options_for(action, resource, method)      map.named_route("#{action}_#{resource.name_prefix}#{resource.singular}", "#{resource.member_path}#{resource.action_separator}#{action}", action_options)      map.named_route("formatted_#{action}_#{resource.name_prefix}#{resource.singular}", "#{resource.member_path}#{resource.action_separator}#{action}.:format",action_options)    end  end  show_action_options = action_options_for("show", resource)  map.named_route("#{resource.name_prefix}#{resource.singular}", resource.member_path, show_action_options)  map.named_route("formatted_#{resource.name_prefix}#{resource.singular}", "#{resource.member_path}.:format", show_action_options)  update_action_options = action_options_for("update", resource)  map.connect(resource.member_path, update_action_options)  map.connect("#{resource.member_path}.:format", update_action_options)  destroy_action_options = action_options_for("destroy", resource)  map.connect(resource.member_path, destroy_action_options)  map.connect("#{resource.member_path}.:format", destroy_action_options)end

Here, we can intuitively see that rails generates many route for the member-related methods of resource. We can see the familiar show, update, and destroy actions in the controller. Yes. Here, rails generates the corresponding route for the URL-to-controller action.

 

This article from: http://woody-420420.javaeye.com/blog/174352

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.