November 21, 2014
Hot Topics:

Techniques to Pass and Read URL Parameters Using Rails

  • February 19, 2009
  • By Raveendran, Arumugam, Rao, and Nanjundappa
  • Send Email »
  • More Articles »

Rails Parameters and Net::Http

Rails has some peculiar characteristics when one tries to send parameters using Net:HTTP. Take the case of Uri shown in the Listing 3 when using Net::HTTP with the Uri shown in Listing 3 with 'Accept' => 'text/xml' or 'Accept' => 'image/jpeg' and so forth because the second argument will result in an a additional parameter "A"=>"" in the params(Hash) for 'post' and 'put' methods.

Listing 3.

response = http.post('/controller/action?id=1&type=user,
   'Accept' => 'text/xml')


This results in an internal construction like this: params = {"id"=>1,"type"=>"user","A"=>""} => {"id"=>1,"type"=>"user","A"=>""}

This may cause problems when parameters are used as a whole in any assignment or operation. Take the case of the example shown in Listing 4 where an attempt is made to find a tuple based on the parameters (condition) passed in Listing 3. Although the user is passing only two parameters—id and type—in the snippet shown in Listing 3, an additional parameter appears in the implicit parameter HashArray "params" by name "A". The existence of this parameter "A" may cause the lookup (query) to fail.

Listing 4.

model_obj = Model.find(:all,:conditions=>params)

The following error occurs:
ActiveRecord::StatementInvalid:
   Mysql::Error: Unknown column 'model.A' in 'where clause':
   SELECT * FROM model WHERE (model.`A` = ''
   AND model.`id` = 1 AND model.`type` = 'user')

The solution is to use an empty argument in post or put the request as shown in Listing 5.

Listing 5.

response = http.post('/controller/action?id=1&type=user,'')

or by explicitly removing the parameter "A".

Passing a parameter with name "A" in

http.post('/controller/action?A=abcd&id=1&type=user,'Accept'
   => 'text/xml')

will overwrite the empty "A"=>"").

NOTE
The above problem does not occur when using CURL.

Rails Parameters and Functional Tests

Typically, data is passed from the functional (or unit) tests in Rails, as shown in Listing 6. In Listing 6, the user passed three parameters, "id", "name", and "type", respectively.

post :create, :id => 300, :name => "ravi", :type => 1

The common notion about Rails is that the parameters are passed as a simple string. However, this is not the case as discussed in the section titled "Rails Parameters and HashMaps." Rails parameters get captured in a HashMap; that holds true in the case of functional or unit tests as well. In the case of regular URL parameters like the ones passed from a browser or Net::Http, interpretation of the parameters as a simple string might still hold good and one may be able to parse the parameters and do validations with simple string search, regular expressions, or sophisticated tools like Treetop. The parsing of the parameters as strings works very well too with a tool like Treetop. However, on the flip side, once the user has done all the unit testing of the controller and jumps into writing the Rails Functional Tests, the user realizes that the parsing of the URL parameters as a simple string doesn't hold good any longer. This is so because paramters passed through controller tests, as shown in Listing 6, get passed as a "pair" in a HashMap and not as a string. It is always wise to read the parameters shown in Listing 2 as parameters.

Summary

This particular article discussed a set of wrong notions that users have about Rails parameters and how one needs to deal with them in real life.

To Contact the Authors


Tags: RoR



Page 2 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel