2015-08-26 38 views
1

我正在學習Ruby on Rails,並好奇params方法如何工作。我明白它的作用,但是如何?Rails params如何解析字符串中的哈希值

是否有一個內置的方法,它的哈希字符串,像這樣

"cat[name]" 

,並將其轉換到

{ :cat => { :name => <assigned_value> } } 

我試圖自己寫params方法,但不知道如何在ruby中編寫這個功能。

回答

0

下面是該方法功能的複製(注意:這不是該方法的工作原理)。幫手感興趣的方法:#array_to_hash#handle_nested_hash_array

require 'uri' 

class Params 
    def initialize(req, route_params = {}) 
    @params = {} 

    route_params.keys.each do |key| 
     handle_nested_hash_array([{key => route_params[key]}]) 
    end 

    parse_www_encoded_form(req.query_string) if req.query_string 
    parse_www_encoded_form(req.body) if req.body 
    end 

    def [](key) 
    @params[key.to_sym] || @params[key.to_s] 
    end 

    def to_s 
    @params.to_s 
    end 

    class AttributeNotFoundError < ArgumentError; end; 

    private 

    def parse_www_encoded_form(www_encoded_form) 
    params_array = URI::decode_www_form(www_encoded_form).map do |k, v| 
     [parse_key(k), v] 
    end 

    params_array.map! do |sub_array| 
     array_to_hash(sub_array.flatten) 
    end 

    handle_nested_hash_array(params_array) 
    end 

    def handle_nested_hash_array(params_array) 
    params_array.each do |working_hash| 
     params = @params 

     while true 
     if params.keys.include?(working_hash.keys[0]) 
      params = params[working_hash.keys[0]] 
      working_hash = working_hash[working_hash.keys[0]] 
     else 
      break 
     end 

     break if !working_hash.values[0].is_a?(Hash) 
     break if !params.values[0].is_a?(Hash) 
     end 

     params.merge!(working_hash) 
    end 
    end 

    def array_to_hash(params_array) 
    return params_array.join if params_array.length == 1 

    hash = {} 
    hash[params_array[0]] = array_to_hash(params_array.drop(1)) 

    hash 
    end 

    def parse_key(key) 
    key.split(/\]\[|\[|\]/) 
    end 
end