Grape API Arrays of Hashes - ruby-on-rails

I am using the grape gem version 0.19.0.
I am passing the following data:
{references: [{x: '10'}, {x: '20'}, {x: '30'}]}
The validation section on the server is:
params do
optional :references, type: Array do
optional :x, type: String
end
end
This does not enter my API call on the server and the client gets the following response:
responseText: "{"error":"references is invalid"}"
How do I pass an array of hashes?

Related

Rspec, how to expect to receive with only a subset of key value pair?

I have a spec that expects a class to receive a method with some arguments. I only want to check for a subset of key/value pair from the arguement hash :
it 'calls Stripe::Checkout::Session#create with the correct line items' do
expect(Stripe::Checkout::Session).to receive(:create).with({
line_items: [{
price: "bla",
quantity: 1
}],
}
)
subject
end
here I only want to check that line_items is present in the argument hash with the correct value.
However the actual hash received has more values and I get the following error :
#<Stripe::Checkout::Session (class)> received :create with unexpected arguments
expected: ({:line_items=>[{:price=>"bla", :quantity=>1}]}, *(any args))
got: ({:allow_promotion_codes=>true, :automatic_tax=>{:enabled=>true}, :billing_address_collection=>"requir...vh.me/fr/thank-you?checkout_session_id={CHECKOUT_SESSION_ID}", :tax_id_collection=>{:enabled=>true}}, {:stripe_account=>"bla"})
How can I tell rspec to only check for the presence of a subset of key/value pair ?
You want hash_including, which matches subsets of hashes:
...to receive(:create).with(hash_including(
line_items: [{
price: "bla",
quantity: 1
}],
)
See the docs: https://relishapp.com/rspec/rspec-mocks/v/3-2/docs/setting-constraints/matching-arguments

Send integer data by swagger/postman in rails api

I am submitting a form by swagger ui(as well as from postman)
param :form, 'user[role]', :string, :required . In the user model role is a enum containing the values like enum role: [1,2,3] . So In the paramters , I am sending 1 in the form field , but I am receiving like {"user" => {"role" => "1"}} which is correct. But the user form is giving error role '1' is not a valid type
Ruby 2.4
Rails 5.1.3
Why use enum when you are passing an array?. I use enums with a hash like this:
enum role: {
customer: 1,
seller: 2,
"6.5": 2,
"5.5": 0
}
And then you pass at the params
{"user" => {"role" => "admin"}}
Which save 0 at the instance for this case

Rails API: Cannot whitelist JSON field attribute

I'm building a rails API with a model containing an attribute data of JSON type. (PSQL)
But when I try to post something like this
{ model: { name: 'Hello', data: { a: 1, b: 2 } } }
Rails thinks a and b are the attributes of a nested data association... It considers then they are unpermitted params.
The thing is, { a: 1, b: 2 } is the value of my field data.
How to provide JSON value to an attribute ?
-
Edit:
The error displayed is:
Unpermitted parameters: name, provider, confidence, location_type, formatted_address, place_id, types, locality, ...
The value of the data attribute is { name: 'Name', provider: 'Provider', ... }
Like I said Rails thinks they are the attributes of a nested data association.
-
Log:
Pastebin
if the keys are unknown in advance this could be a workaround:
def model_params
data_keys = params[:model].try(:fetch, :data, {}).keys
params.require(:model).permit(data: data_keys)
end
Credit goes to aliibrahim, read the discussion https://github.com/rails/rails/issues/9454 (P.S seems like strong parameters will support this use case in Rails 5.1)
When you post something, you have to make sure that your json have the same parameters that your controller.
Example rails api:
def example
#model = Model.new(params)
#model.save
render(json: model.to_json, status: :ok)
end
def params
params.permit(:name, :provider, {:data => [:a, :b]})
end
Example front-end json for post:
var body = {
name: 'myName',
provider: 'provider',
data: {
a: 'something',
b: 'otherthing',
}
};
For some reason rails doesnt recognize a nested json, so you need to write into params.permit that data will be a json with that syntax, if where a array, the [] should be empty.

receive Array of hashes in API call rails

I 'm working on rails app in which I need to receive array of hashes in API call with Grape like.
{
tournament_id:1
match_id: 10
[
{
team_id: 1
score: 10
},
{
team_id: 2
score: 20
}
]
}
so that I can receive score of each team in single call for a specific match and tournament instead of multiple calls for score of each team.
I have tried multiple things like
group :teams_with_scores, type: Array, desc: "An array of Teams with scores" do
requires :team_id, type: String,desc: "Team ID"
requires :score, type: String,desc: "Score"
end
But don't have a clue that how to do it.
You can send this data as a json string, and then parse this json when you get it:
params do
scores_info, type: String, desc: 'the scores info'
end
get do
scores_info = JSON.parse(params[:scores_info])
end

Active record result and transformed JSON

I need to transform active record JSON to something like this:
{
cols: [{id: 'task', label: 'Task', type: 'string'},
{id: 'hours', label: 'Hours per Day', type: 'number'}],
rows: [{c:[{v: 'Work'}, {v: 11}]},
{c:[{v: 'Eat'}, {v: 2}]},
{c:[{v: 'Commute'}, {v: 2}]},
{c:[{v: 'Watch TV'}, {v:2}]},
{c:[{v: 'Sleep'}, {v:7, f:'7.000'}]}
]
}
That is totally different from what to_json returns from activerecord. What is the most ruby way to transform JSON?
Override the to_json method in your model
# your_model.rb, implement an instance method to_json
def to_json(options = {})
{
'cols' => [{'id' => 'whateveryoulike'}],
'rows' => [{'id' => 'whateveryoulike'}]
}.to_json(options)
end
Remember, it is important to accept options as parameter to this method and pass it on to to_json of the hash (or any other to_json call you make inside this method, for that matter). Otherwise, the method may not behave as expected on collection JSON serialization. And of course since you haven't given any details as to what your model is and how it maps to the desired JSON response, you will have to implement the representation of cols and rows as you like.
This also applies to to_xml.

Resources