I have some params that I need to reshape?
I've got an old database I'm trying to build a new app on top of to access and do CRUD operations on.
I simply need to make this structure...
{
"volunteer_shift_attributes"=><ActionController::Parameters{
"volunteer_task_type_id"=>"41",
"roster_id"=>"7",
"program_id"=>"9",
"set_description"=>"ddddddddddd"
} permitted: true>,
"set_date"=>"2021-01-14",
"contact_id"=>"166574",
"closed"=>"0",
"start_time(4i)"=>"14",
"start_time(5i)"=>"00",
"end_time(4i)"=>"15",
"end_time(5i)"=>"00",
"notes"=>"nnnnnnnnnnnnn",
}
have this structure...
{
"volunteer_shift_attributes"=>{
"volunteer_task_type_id"=>"41",
"roster_id"=>"7",
"program_id"=>"9",
"set_description"=>"ddddddddddd"
},
"set_date"=>"2021-01-15",
"contact_id"=>"166574",
"closed"=>"0",
"start_time(4i)"=>"14",
"start_time(5i)"=>"00",
"end_time(4i)"=>"15",
"end_time(5i)"=>"00",
"notes"=>"aaaaaaaaaaaaaa"
}
NOTE: this is called inside a controller method like so
def create_shift
...
a.attributes = (params["assignment"])
...
end
I need to rebuild this param by hand.
It's not clear exactly why you need to do this - they're just params and you're not looking to change the structure, exactly. But it looks like it could be a case for strong params. Define a private method:
def volunteer_shift_params
params.require(:volunteer_shift_attributes)
.permit(:volunteer_task_type_id,
:roster_id,
:program_id,
:set_description)
end
Then, you should be able to do this, as you asked:
a.attributes = volunteer_shift_params
Related
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
Because Rails utilize "strong parameters" you have to list and allow the parameters in the controller you want to use.
Since you have a list of parameters with dynamic keys the easiest way to do, while you are in development mode is to permit them like this:
# in your controller
def game_params
params.require(:game).tap do |permitted|
permitted[:name] = params[:name].permit!
permitted[:snake] = params[:snake].permit!
permitted[:apple] = params[:apple].permit!
permitted[:skull] = params[:skull].permit!
permitted[:completed] = params[:completed].permit!
end
end
and then you will be able to access your params:
game_params[:snake][:body]
In production tho, I will encourage you to whitelist all of the keys, for example like this.
I would like to get any additional GET and POST params in Rails without Rails' own additions such as controller, format, etc...
params.inspect gave me what I want but it has some keys that Rails adds for me such as controller or format. I only want to get user input GET and POST params as hash. How can I do that? I cannot find anything.
URL:
http:/test.com/some/path?query1=1&query2=1
Run:
puts params.inspect
Expected:
{"query1"=>"1", "query2"=>"1"}
Actual:
{"query1"=>"1", "query2"=>"1", "format"=>":json", "controller"=>"get", "action"=>"index", "folder"=>"some/path"}
Also this can be combined with POST request. I only want to filter them and only get them as hash.
I execute this from inside of a controller. Rails 5 used.
You should have permitted params (Strong parameters).
In your controller have permitted params method.
def your_params
params.permit(:query1, :query2)
end
If you wish to have a hash of those you can do
your_params.to_h #This will return hash of permitted params
Update:
Incase you have multiple query* type of parameters you can select them and permit!. Here is a command line explanation
# passing the list of parameters
> params = ActionController::Parameters.new({query1: 'aa', query2: 'bb', query3: 'cc', controller: 'users', action: 'index'})
=> <ActionController::Parameters {"query1"=>"aa", "query2"=>"bb", "query3"=>"cc", "controller"=>"users", "action"=>"index"} permitted: false>
# Select all the parameters of type query<integer>
> all_queries = params.select {|i| i.match?(/query\d/) }
=> <ActionController::Parameters {"query1"=>"aa", "query2"=>"bb", "query3"=>"cc"} permitted: false>
# mark the selected as permitted
> all_queries.permit!
=> <ActionController::Parameters {"query1"=>"aa", "query2"=>"bb", "query3"=>"cc"} permitted: true>
# get them as hash
> all_queries.to_h
=> {"query1"=>"aa", "query2"=>"bb", "query3"=>"cc"}
Controller method will look like
# getting all query<integer> like params
def your_params
params.select {|param| param.match?(/query\d/}.permit!
end
In the controller, you have access to a request object. request has a method query_parameters, which will return a hash of just the explicitly supplied parameters.
`request.query_parameters`
http://api.rubyonrails.org/classes/ActionDispatch/Request.html#method-i-query_parameters
I put in a binding.pry at the top of my controller's update action. Once at that break point, I put in params[:foo_bar] to examine the params hash. Here is what I get:
<ActionController::Parameters {"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"123==", "foobar"=><ActionController::Parameters {"barbazz_attributes"=>{"start_date"=>"08/27/2016", "end_date"=>"08/29/2016", "id"=>"89"}, "bazz_id"=>"3", "abc_id"=>"330", "bazzbazz_attributes"=>{"0"=>{"_destroy"=>"1", "city_id"=>"1669", "id"=>"26"}, "1"=>{"city_id"=>"1681", "id"=>"27"}, "2"=>{"city_id"=>"1672"}}} permitted: false>, "cat_id"=>["1", "1", "1"], "commit"=>"Update FooBar", "controller"=>"foo_bars", "action"=>"update", "id"=>"52"} permitted: false>
I assumed permitted: false is there because I did not whitelist some attributes. I looked over the attributes and it appears to me that I did whitelist everything.
I am using Rails 5 if that happens to make any difference.
Question: What is an easy way to find out why the strong parameters are returning params: false.
Don't access params directly with params instead use the name you gave your permitted params, for example: foobar_params.
If foobar_params is defined:
def foobar_params
params.require(:foobar).permit ...
end
The easiest way is to read the source code for ActionController::Parameter, permitted = false is the default unless you call permit! to allow all, but that defeats the purpose of strong parameters.
In my Ruby on Rails application i have the following params:
{"0"=>{"from_days"=>"1", "to_days"=>"2", "netto_price"=>"1.0", "_destroy"=>"false", "id"=>"57"}, "1"=>{"from_days"=>"3", "to_days"=>"7", "netto_price"=>"23", "_destroy"=>"false"}, "2"=>{"from_days"=>"9", "to_days"=>"10", "netto_price"=>"123", "_destroy"=>"false"}}
Now i want to check that:
1[:from_days] > 0[:to_days]
2[:from_days] > 1[:to_days]
etc.
Problem is that I want to do it dynamically because in future this parameters will grow up. Did anyone have idea how to solve this problem?
You can try this:
params = {"0"=>{"from_days"=>"1", "to_days"=>"2", "netto_price"=>"1.0", "_destroy"=>"false", "id"=>"57"}, "1"=>{"from_days"=>"3", "to_days"=>"7", "netto_price"=>"23", "_destroy"=>"false"}, "2"=>{"from_days"=>"9", "to_days"=>"10", "netto_price"=>"123", "_destroy"=>"false"}}
(params.keys.min..params.keys.max).each do |index|
if params[(index+1).to_s][:from_days].to_i > params[index.to_s][:to_days].to_i
# your logic when 1[:from_days] > 0[:to_days] is true
else
end
end
This code implies that your params hash :
must contain consecutive keys (no gap between each)
must contain a hash having the [:from_days] AND the [:to_days] keys
I have the following hash and I'm looking for an easy way to check if everything is empty in the hash. Not all values are always visible in the hash so sometimes the hash is without end_date / start_date or anything else.
test
=> {"0"=>
{"_destroy"=>"",
"START_DATE"=>"",
"END_DATE"=>"",
"EMPLOYER"=>"",
"JOB_TITEL"=>"",
"FUNCTIONAL_AREA"=>"",
"INDUSTRY"=>"",
"DESCRIPTION_TXT"=>"",
"COUNTRY"=>"",
"CITY"=>"",
"REGION"=>"",
"CONTRACT_TYPE"=>""},
"1"=>
{"_destroy"=>"",
"START_DATE"=>"",
"END_DATE"=>"",
"EMPLOYER"=>"",
"JOB_TITEL"=>"",
"FUNCTIONAL_AREA"=>"",
"INDUSTRY"=>"",
"DESCRIPTION_TXT"=>"",
"COUNTRY"=>"",
"CITY"=>"",
"REGION"=>"",
"CONTRACT_TYPE"=>""},
"2"=>
{"_destroy"=>"",
"START_DATE"=>"",
"END_DATE"=>"",
"EMPLOYER"=>"",
"JOB_TITEL"=>"",
"FUNCTIONAL_AREA"=>"",
"INDUSTRY"=>"",
"DESCRIPTION_TXT"=>"",
"COUNTRY"=>"",
"CITY"=>"",
"REGION"=>"",
"CONTRACT_TYPE"=>""}}
In pseudocode it would like this
Start loop
-> check if current position contains an empties
=> if all is empty delete position
-> continue
end loop
In this example it means that the hash will be empty at the end of the loop.
Kind regards
Use Hash#delete_if:
test.delete_if { |i,h| h.all? { |k,v| v.empty? } }