I have a controller in ruby on rails 4 and i need to pre-process its params during request processing.
I receive parameters:
{"_json"=>[{"date"=>"9/15/2014", "name"="James"},{"date"=>"2/11/2014","name"=>"John"}]}
And i need to iterate through all json array elements and update name parameter by adding 'User' post fix. So, finally my json should be:
[{"date"=>"9/15/2014", "name"="James **User**"},{"date"=>"2/11/2014","name"=>"John **User**"}]
How can i do it in my controller?
You can try this way
params = {"_json"=>[{"date"=>"9/15/2014", "name"=>"James"},{"date"=>"2/11/2014","name"=>"John"}]}
Then modify params using using
params["json"].each { |h| h["name"] = "#{h['name']} **User**" }
puts params["_json"]
if you want to preprocess for each action then used before_filter
Related
Submitting the following parameters
Parameters: {[...] "physicalinventario"=>{[...] "physicalinventarioitems_attributes"=>{"0"=>{"quantity"=>",85"}}}, "commit"
The goal is to intercept the quantity parameter at the physicalinventarioitem controller create action, and sanitize it for possible comma as decimal value being input
if params[:physicalinventario][:physicalinventarioitems_attributes][:quantity].include? ","
params[:physicalinventarioitem][:quantity] = params[:physicalinventario][:physicalinventarioitems_attributes][:quantity].tr!(',', '.').to_d
end
However, the syntax is wrong as no value after the comma is being handled.
#Alex answer is fine if you have only one quantity.
but what if you have multiple quantites,
eg: {"0"=>{"quantity"=>",85"},"1"=>{"quantity"=>",90"}}
So, here is the answer which also achieves that requirement for multiple nested attributes.
hash = {"physicalinventario"=>{"physicalinventarioitems_attributes"=>{"0"=>{"quantity"=>",85"},"1"=>{"quantity"=>",90"}}}}
The code that you require,
hash["physicalinventario"]["physicalinventarioitems_attributes"].each do |key, value|
if value["quantity"].include? ","
value["quantity"] = value["quantity"].tr!(',', '.').to_f
end
end
Here is the resultant hash,
`{"physicalinventario"=>{"physicalinventarioitems_attributes"=>{"0"=>{"quantity"=>0.85}, "1"=>{"quantity"=>0.9}}}}`
Looks like you've missed ["0"] in the chain to get :quantity.
Should be
params[:physicalinventario][:physicalinventarioitems_attribu‌tes]["0"][:quantity]
Most convenient Rails way to sanitize(normalize) data in a model.
To don't create duplicates, more here How best to sanitize fields in ruby on rails
I am having problems accessing the attributes of my JSON data. Instead of accessing the JSON data it thinks it is a function.
#response = HTTParty.get('http://localhost:4000/test')
#json = JSON.parse(#response.body)
#json.each do |pet|
MyModel.create(pet) ! WORKS
puts "my object #{pet}" ! WORKS
puts "my object attribute #{pet.myattribute}" ! DOES NOT WORK
end
With no MethodError myattribute.
Thank you for any help!
You may be used to JavaScript, where both object.some_key and object["some_key"] do the same thing. In Ruby, a hash is just a hash, so you have to access values via object["some_key"]. A Struct in Ruby is similar to a JavaScript object, in that you can access values both ways, but the keys have to be pre-defined.
#json = JSON.parse(#response.body) returns a hash, so you would need to do
puts "my object attributes #{pet['id']}, #{pet['title']}"
you might want to convert to HashWithIndifferentAccess so you can use symbols instead of quoted strings, i.e.
#json = JSON.parse(#response.body).with_indifferent_access
# ...
puts "my object attributes #{pet[:id]}, #{pet[:title]}"
I am doing an http get using the url http://localhost/add?add_key[0][key]=1234&add_key[0][id]=1.
I have a rails app which gives me a neat params hash {"add_key"=>{"0"=>{"key"=>"1234", "id"=>"1"}}. However when I try to post this to a different server using
new_uri = URI.parse("http://10.10.12.1/test")
res = Net::HTTP.post_form new_uri,params
The server handling the post is seeing this parameter in the request
{"add_key"=>"0key1234id1"}
Looks like post_form requires a String to String hash. So how do I convert the params hash to
{"add_key[0][key]" => "1234", add_key[0][id]" => "1"}
From the fine manual:
post_form(url, params)
Posts HTML form data to the specified URI object. The form data must be provided as a Hash mapping from String to String.
So you're right about what params needs to be.
You could grab the parsed params in your controller:
{"add_key"=>{"0"=>{"key"=>"1234", "id"=>"1"}}
and then recursively pack that back to the flattened format that post_form expects but that would be a lot of pointless busy work. An easy way to do this would be to grab the raw URL and parse it yourself with URI.parse and CGI.parse, something like this in your controller:
u = URI.parse(request.url)
p = CGI.parse(u.query)
That will leave you with {"add_key[0][key]" => "1234", "add_key[0][id]" => "1"} in p and then you can hand that p to Net::HTTP.post_form.
I would like to save query result into redis using JSON serialization and query it back.
Getting query results to json is pretty easy:
JSON.generate(Model.all.collect {|item| item.attributes})
However I did not find a proper way to deserialize it back to ActiveRecord. The most straight-forward way:
JSON.parse(#json_string).collect {|item| Model.new.from_json(item)}
Gives me an error:
WARNING: Can't mass-assign protected attributes: id
So id gets empty. I thought of just using OpenStruct for the views instead of ActiveRecord but I am sure there is a better way.
You could instantiate the new object from JSON and then assign the id afterwards. Probably best to create your own method for this:
class Model
def self.from_json_with_id(params = {})
params = JSON.parse(params)
model = new(params.reject {|k,v| k == "id"})
model.id = params["id"]
model
end
end
Or maybe just override the from_json() method.
Why not like this:
JSON.parse(#json_string).each do |item|
item.delete(:id) # I tested it in my case it also works without this line
object=Model.create(item)
end
If the host that created the JSON adds a JSON root you might have to use item[1] instead of item.
Hi
I want to use two params hashes in one page
The job of this page is straightforward, it's an edit page, and I want it to send out notifications to a server once the editing job is done.
def update
#description = Tempdescription.find(params[:id])
#description.update_attributes(params[:tempdescription])
sendnotification
end
def sendnotification
params[:to_ids]="xxxx"
sig = hash_params(params);
params[:sig] = sig
response = RestClient.post "http://api.xxxx.com/restserver.do", params, :content_type => :json, :accept => :json
render :text=>response
end
def hash_params(params)
params = Hash[*params.sort.flatten]
payload = ''
params.sort.each do |pair|
key, value = pair
payload = payload + "#{key}=#{value}"
end
return Digest::MD5.hexdigest(payload + API_SECRET)
end
Not surprisingly the params in sendnotification also includes params used for updating
and the server returns 104 error
Therefore,
I tried
new_params=Hash[]
and use new_params to replace the old params in sendnotification
But then rails complains
undefined method `<=>' for :session_key:Symbol
app/controllers/tempdescriptions_controller.rb:72:in `<=>'
app/controllers/tempdescriptions_controller.rb:72:in `sort'
app/controllers/tempdescriptions_controller.rb:72:in `hash_params'
app/controllers/tempdescriptions_controller.rb:45:in `sendnotification'
So I am thinking if there is any way I can create another params?
Thanks in advance
Ok, having complained about your formatting I suppose I should hazard an attempt at your problem.
This code:
def hash_params(params)
params = Hash[*params.sort.flatten]
payload = ''
params.sort.each do |pair|
key, value = pair
payload = payload + "#{key}=#{value}"
end
return Digest::MD5.hexdigest(payload + API_SECRET)
end
.. appears to accept a hash as its argument and then recreate it with the keys sorted. Presumably this code is targeted at ruby 1.9 otherwise that would be rather pointless. It then sorts again for no reason I can determine before joining the keys and values with = but without separating the pairs with &.
The error is a little mysterious though; I have no trouble sorting symbols with ruby 1.9. Perhaps you're running ruby 1.8?
Ok...after playing with rails console for a while I finally find a solution to this problem.
In sendnotification method I created a new hash
p=Hash[]
but simply putting this will not work, as I mentioned before.
Then I changed all
p[:key]
to
p["key"]
and it works.
Obviously Hash#sort doesn't work with hash[:key] if the hash is newly created but it works with params and that's what puzzled me and made me believe there is a difference between params and normal hash.
I am using Ruby 1.8.7 so I think it might just be a bug of this version.