My form receives data via POST. When I do puts params
I can see:
{"id" => "123", "id2" => "456"}
now the commands:
puts params['id'] # => 123
puts params[:id] # => 123
params['id'] = '999'
puts params # => {"id" => "999", "id2" => "456"}
but when I do:
params[:id] = '888'
puts params
I get
{"id" => "999", "id2" => "456", :id => "888"}
In IRB it works fine:
params
# => {"id2"=>"2", "id"=>"1"}
params[:id]
# => nil
params['id']
# => "1"
Why can I read the value using :id
, but not set the value using that?
Params is short for the word parameter. A parameter is a key-value pair that is encoded in a HTTP request. There are three kinds of params: user supplied parameters , routing parameters , and default parameters .
params[:id] is meant to be the string that uniquely identifies a (RESTful) resource within your Rails application. It is found in the URL after the resource's name.
Hashes in Ruby allow arbitrary objects to be used as keys. As strings (e.g. "id"
) and symbols (e.g. :id
) are separate types of objects, a hash may have as a key both a string and symbol with the same visual contents without conflict:
irb(main):001:0> { :a=>1, "a"=>2 }
#=> {:a=>1, "a"=>2}
This is distinctly different from JavaScript, where the keys for objects are always strings.
Because web parameters (whether via GET or POST) are always strings, Sinatra has a 'convenience' that allows you to ask for a parameter using a symbol and it will convert it to a string before looking for the associated value. It does this by using a custom default_proc that calls to_s
when looking for a value that does not exist.
Here's the current implementation:
def indifferent_hash
Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
end
However, it does not provide a custom implementation for the []=(key, val)
method, and thus you can set a symbol instead of the string.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With