Using javascript, I make a fetch post.
const game = {name: this.player, snake: this.snake, score: this.score, apple: this.apple, skull: this.skull, completed: this.completed}
return fetch("http://localhost:3000/games", {
method: "POST",
headers: {
"Content-Type": "application/json"},
body: JSON.stringify(game)
})
.then(resp => resp.json())
.then(json => Game.appendHighScores(json));
I access the data via params on the Ruby on Rails end. The data for params[:snake][:body]
are supposed to look like "body"=>[{"x"=>16, "y"=>15}, {"x"=>16, "y"=>14}, {"x"=>16, "y"=>15}]}
, yet when I type them into the command line, they look like this:
[<ActionController::Parameters {"x"=>16, "y"=>15} permitted: false>, <ActionController::Parameters {"x"=>16, "y"=>14} permitted: false>, <ActionController::Parameters {"x"=>16, "y"=>15} permitted: false>]
It is accessible via indexing, but I get everything along with the data I'm looking for.
I was hoping it would look like the original params when I typed it in
<ActionController::Parameters {"name"=>"Don", "snake"=>{"x"=>16, "y"=>15, "direction"=>"down", "speed"=>0, "directions"=>{"left"=>{"x"=>-1, "y"=>0}, "up"=>{"x"=>0, "y"=>-1}, "right"=>{"x"=>1, "y"=>0}, "down"=>{"x"=>0, "y"=>1}}, "image"=>{}, "body"=>[{"x"=>16, "y"=>15}, {"x"=>16, "y"=>14}, {"x"=>16, "y"=>15}]}, "score"=>0, "apple"=>{"image"=>{}, "x"=>2, "y"=>10}, "skull"=>{"image"=>{}, "x"=>12, "y"=>12}, "completed"=>true, "controller"=>"games", "action"=>"create", "game"=>{"score"=>0, "skull"=>{"image"=>{}, "x"=>12, "y"=>12}, "apple"=>{"image"=>{}, "x"=>2, "y"=>10}, "completed"=>true}} permitted: false>
Anyway to get the params as an array without it looking so messy with ActionController::Parameters
inside of the element?
The reason everything is wrapped inside ActionController::Parameters
is for your security (mass assignment in particular). You should never trust data send from the internet. This class allows you to permit/whitelist what properties you trust and filter out everything that you don't trust.
snake_params = params.require(:snake).permit(body: [:x, :y])
You can then convert this into a hash with a simple to_h
call, which will drill down into all other nested parameters that are also permitted.
snake_data = snake_params.to_h
#=> { "body" => [{"x"=>16, "y"=>15}, {"x"=>16, "y"=>14}, {"x"=>16, "y"=>15}] }
If you'd like to include other attributes as well you can add them to the permit
list.
.permit(:direction, :speed, directions: {left: [:x, :y], up: [:x, :y], ...}, body: [:x, :y])
For more info about permit
I suggest checking out the guide Action Controller Overview - 4.5 Strong Parameters.
If you don't care about permitting certain parameters you can permit everything with permit!
.
Note that you don't have to permit parameters if you extract the values directly. The code below would work perfectly fine without permitting anything.
body = params[:snake][:body]
body.each |body_part|
x = body_part[:x]
y = body_part[:y]
// do stuff with x and y
end