Accessing a Hash in a REST POST - ruby-on-rails

I have a hash in Ruby:
params={"username"=>"test"}
I want to add another associative array like:
params["user"]={"name"=>"test2"}
so params should become
params={"username"=>"test","user"=>{"name"=>"test2"}}
but when I post this params to a url, I get:
params[:user][:name] # => nil
when I dump the user data:
params[:user] # => ['name','test2']
what I want is
params[:user] # => output {'name'=>'test2'}
what am I doing wrong? thanks for help.

You're just using wrong key, you think that :user and "user" are the same, which is not.
params["user"]["name"] #=> "test2"
params["user"] #=> {"name"=>"test2"}
UPDATE from Naveed:
:user is an instance of Symbol class while "user" is instance of String

You have created a hash with keys of type string and trying to access with symbol keys. This works only with class HashWithIndifferentAccess.
If you want to achieve the same convert your hash to HashWithIndifferentAccess by using with_indifferent_access method,
> params = {"username"=>"test", "user"=>{"name"=>"test2"}}
=> {"username"=>"test", "user"=>{"name"=>"test2"}}
> params[:user][:name]
=> nil
>params = params.with_indifferent_access
> params[:user][:name]
=> "test2"
Update: request params is an instance of HashWithIndifferentAccess

The following should work:
params["user"]

params={"username"=>"test"}# params is not array nor associative array its a hash
you can add key value pair in hash by
params["key"]="value"
key and value both can be object of any class,be sure you use same object as key to access value or take a look at
HashWithIndifferentAccess
now
params["user"]={"name"=>"blah"}
params["user"] # => {"name"=>"blah"}
params["user"]["name"] # => "blah"

Related

Rails 5 Permitting controller action changed params

So i have the following params permitted.
p = params.permit(:a, :b, :c, :lines => [:location_id, :quantity, :product => [:id]])
In my controller action, i add to the lines param the data i've permitted.
p['lines'] << {"product"=>{"id"=>"123456"}, "quantity"=>"2", "location_id"=>"123456"}
This is how the params looked after they've been changed.
puts params['lines']
#> [<ActionController::Parameters {"product"=>{"id"=>"123456"}, "quantity"=>"2", "location_id"=>"123456"} permitted: false>]
But as you can see it's not permitted. What am i missing here? I am using Rails 5.
To get permitted (whitelisted) params, you always have to make sure that you call the permitted version, p in your case, whenever params changes.
The difference between params and p is that params.permit(...) returns a permitted copy of itself and assigns it to p. So params permission state remains unchanged.
Try with puts p['lines'] instead of puts params['lines'] to see if you get the desired result.

Accessing value(s) of ActionController Parameters hash

I'm having trouble with parameters in an app upgraded from 4.2 to 5.1. I have permitted my parameters, but as the documentation states, I'm getting back an object for my hash array, but can't seem to access the values of it. How can I just get the value of this object?
{"_method"=>"delete", "authenticity_token"=>"Z6ZqriiuXu6ODDqhGgocGiaN12rjKD6pUB6n/2v+CABZDAjwLzwczsMM3nM8f0PI0nww43o5mlC35HK+9PVa8w==",
"domain_name"=>"test.testmodule2.com.",
"hosted_zone_id"=>"/hostedzone/XXXXXXXXXX",
"ttl"=>"3600",
"type"=>"A",
"value"=>[{"value"=>"1.1.1.1"}],
"id"=>"/hostedzone/XXXXXXXXXX"}
def record_params
params.permit!([:hosted_zone_id, :domain_name, :type, :ttl, :alias, :value]).to_h!
end
def destroy
value = params[:value]
# returns [<ActionController::Parameters {"value"=>"1.1.1.1"} permitted: true>]
# would like it to return [{"value"=>"1.1.1.1"}]
end
If that hash is the value of params[:value], then access the value key inside, like:
params[:value] = {
"_method"=>"delete",
"authenticity_token"=>"...",
"domain_name"=>"test.testmodule2.com.",
"hosted_zone_id"=>"/hostedzone/XXXXXXXXXX",
"ttl"=>"3600",
"type"=>"A",
"value"=>[{"value"=>"1.1.1.1"}],
"id"=>"/hostedzone/XXXXXXXXXX"
}
params['value']['value'][0]['value']
# => "1.1.1.1"
params['value']['value'][0].keys
# => ["value"]

Rails - permit a param of unknown type (string, hash, array, or fixnum)

My model has a custom_fields column that serializes an array of hashes. Each of these hashes has a value attribute, which can be a hash, array, string, or fixnum. What could I do to permit this value attribute regardless of its type?
My current permitted params line looks something like:
params.require(:model_name).permit([
:field_one,
:field_two,
custom_fields: [:value]
])
Is there any way I can modify this to accept when value is an unknown type?
What you want can probably be done, but will take some work. Your best bet is this post: http://blog.trackets.com/2013/08/17/strong-parameters-by-example.html
This is not my work, but I have used the technique they outline in an app I wrote. The part you are looking for is at the end:
params = ActionController::Parameters.new(user: { username: "john", data: { foo: "bar" } })
# let's assume we can't do this because the data hash can contain any kind of data
params.require(:user).permit(:username, data: [ :foo ])
# we need to use the power of ruby to do this "by hand"
params.require(:user).permit(:username).tap do |whitelisted|
whitelisted[:data] = params[:user][:data]
end
# Unpermitted parameters: data
# => { "username" => "john", "data" => {"foo"=>"bar"} }
That blog post helped me understand params and I still refer to it when I need to brush up on the details.

Rails Strong params when attribute can be string or hash

I have a parameter that can be either a string or a hash (metadata) and I would like to allow both using rails strong params
the problem is that metadata can either be a hash or a String or both
{transactions: [{metadata: "hello"}, metadata: {name: "world"}]}
With the rails params
params.permit(:transactions => [:reference_id, :metadata => ["name"]])
I have the following error
expected Hash (got String) for param `metadata'
I see the only way to permit, is to verify the constant parameters at first, then verify a parameter with variable type:
params.permit(:transactions => [:reference_id, :metadata])
begin
params.permit(:metadata => {})
rescue TypeError
# here check that :metadata is a string
end

Mongoid: Added Hash to Model but can't write to it

I've got a model, Entity.
class Entity
include Mongoid::Document
field :x
field :y
field :z, type => Hash, :default => {} # new field
end
I added a new field to it, a hash. When I try to use it, I get an error. My code is:
e = Entity.first
if e.z["a"] # if there is a key of this in it?
e.z["a"] = e.z["a"] + 1
else
e.z["a"] = 1
end
But, this error with an undefined method get for hash. If I try to create an initializer for it, to set the values in an existing document, it errors with the same error. What am I doing wrong?
Initializer looks like:
e = Entity.first
e.write_attribute(:z, {})
Thanks
Sorted it.
It seems the answer is to set in Mongoid 1.9.5 the hash to:
field :hash_field, :type => Hash, :default => Hash.new
and it can access and initialize it. Not quite understanding why, but happy to have the answer !

Resources