Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #9935: json_request_parsing.3.diff

File json_request_parsing.3.diff, 4.5 kB (added by Assaf, 1 year ago)

New and improved patch to access parameter based on controller name

  • test/controller/request_test.rb

    old new  
    327327    assert_equal Mime::TEXT, @request.format 
    328328  end 
    329329 
     330  def test_json_format 
     331    @request.instance_eval { @parameters = { :format => 'json' } } 
     332    assert_equal Mime::JSON, @request.format 
     333  end 
     334 
    330335  def test_nil_format 
    331336    @request.instance_eval { @parameters = { :format => nil } } 
    332337    @request.env["HTTP_ACCEPT"] = "text/javascript" 
     
    352357    assert_equal Mime::XML, @request.content_type 
    353358  end 
    354359   
     360  def test_content_type_json 
     361    @request.env["CONTENT_TYPE"] = "application/json" 
     362    assert_equal Mime::JSON, @request.content_type 
     363  end 
     364 
    355365  def test_user_agent 
    356366    assert_not_nil @request.user_agent 
    357367  end 
     
    782792      ActionController::CgiRequest.new(cgi).request_parameters 
    783793    end 
    784794end 
     795 
     796 
     797class JsonParamsParsingTest < Test::Unit::TestCase 
     798  def test_json_hash 
     799    params = parse_body(<<-JSON) 
     800      { name: "David", 
     801        url: "http://rubyonrails.org/", 
     802        count: 1 
     803        } 
     804    JSON 
     805 
     806    assert_equal 'David', params['person']['name'] 
     807    assert_equal 'http://rubyonrails.org/', params['person']['url'] 
     808    assert_equal 1, params[:person][:count] 
     809  end 
     810 
     811  def test_json_array 
     812    params = parse_body(<<-JSON) 
     813      [ { name: "David" }, 
     814        { name: "Allan" } ] 
     815    JSON 
     816 
     817    assert_equal 'David', params['people'].first['name'] 
     818    assert_equal 'Allan', params['people'].last['name'] 
     819  end 
     820 
     821  private 
     822    def parse_body(body, controller = nil) 
     823      env = { 'CONTENT_TYPE'   => 'application/json', 
     824              'CONTENT_LENGTH' => body.size.to_s } 
     825      cgi = ActionController::Integration::Session::MockCGI.new(env, body) 
     826      request = ActionController::CgiRequest.new(cgi) 
     827      request.path_parameters = { :controller=>'people' } 
     828      request.send :prepare_request_parameters 
     829      request.parameters 
     830    end 
     831end 
  • lib/action_controller/dispatcher.rb

    old new  
    168168    protected 
    169169      def handle_request 
    170170        @controller = Routing::Routes.recognize(@request) 
     171        @request.send :prepare_request_parameters 
    171172        @controller.process(@request, @response).out(@output) 
    172173      end 
    173174 
  • lib/action_controller/request.rb

    old new  
    339339        @content_type_without_parameters ||= self.class.extract_content_type_without_parameters(content_type_with_parameters) 
    340340      end 
    341341 
     342      # If the _data parameter was set previously by parsing the request body, 
     343      # this method will rename it based on the controller name, so ItemsController 
     344      # sees the :item parameter. 
     345      def prepare_request_parameters 
     346        if _data = request_parameters.delete(:_data) 
     347          name = path_parameters[:controller] 
     348          name = name.singularize unless _data.is_a?(Array) 
     349          request_parameters.update(name=>_data) 
     350        end 
     351      end 
     352 
    342353    private 
    343354      def content_type_from_legacy_post_data_format_header 
    344355        if x_post_format = @env['HTTP_X_POST_DATA_FORMAT'] 
     
    373384            self.class.parse_multipart_form_parameters(body, boundary, content_length, env) 
    374385          when :xml_simple, :xml_node 
    375386            body.blank? ? {} : Hash.from_xml(body).with_indifferent_access 
     387          when :json 
     388            { :_data => ActiveSupport::JSON.decode(body) }.with_indifferent_access 
    376389          when :yaml 
    377390            YAML.load(body) 
    378391          else 
  • lib/action_controller/base.rb

    old new  
    306306    #   ActionController::Base.param_parsers[Mime::YAML] = :yaml 
    307307    @@param_parsers = { Mime::MULTIPART_FORM => :multipart_form, 
    308308                        Mime::URL_ENCODED_FORM => :url_encoded_form, 
    309                         Mime::XML => :xml_simple } 
     309                        Mime::XML => :xml_simple, 
     310                        Mime::JSON => :json } 
    310311    cattr_accessor :param_parsers 
    311312 
    312313    # Controls the default charset for all renders.