create records only when boxes checked - ruby-on-rails

The following PATCH action is getting the following parameters
Parameters: {"utf8"=>"✓", [...], "contractgroup"=>
{"articolocontractgroups_attributes"=>
{"0"=>{"articolo_id"=>"0", "id"=>"425"},
"1"=>{"articolo_id"=>"true", "id"=>"426"},
"2"=>{"articolo_id"=>"true", "id"=>"427"},
"3"=>{"articolo_id"=>"0", "id"=>"428"}}, "contractgroup_id"=>"2"}, "commit"=>"Add"}
however the controller action is invoking the parameters in a mistaken manner, as no records are being created:
params[:contractgroup][:articolocontractgroups_attributes].each do |id, attrs|
if params[:articolo_id] == "true"
#articolocontractgroup = Articolocontractgroup.new
(articolo_id: params[:contractgroup][:articolo_id],
contractgroup_id: params[:contractgroup][:contractgroup_id])
#articolocontractgroup.save
end
end
where is this messed up?

You need to check attrs[:articolo_id] == "true" instead params[:articolo_id]

Related

How to get just GET and POST params as hash in Rails?

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

Why Strong Params contains permitted: false

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.

Comparing hash values

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

undefined method `[]' for nil:NilClass in controller

I have parameter passing in console shows as:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Oj9EGihSOwgdXGLLQWqVESYMP/N4K0KzDS4KyVhWXPg=", "rfp"=>{"user_id"=>"", "client_id"=>"", "othercms"=>"", "otherecommerce"=>"", "numberofpage"=>"", "designcomplexity"=>"", "browser"=>"", "nuhacks"=>"", "nujavascript"=>"", "numberofmenu"=>"", "designpages"=>"", "designformobilepages"=>"", "framworks"=>"", "test_report_ids"=>[""], " payment_gateway_ids"=>[""], "payment_gateway_ids"=>["2"], "**payment_gateways"=>{"name"=>"slsk"}**, "commit"=>"Create Rfp", "project_id"=>"18"}
Controller:
#rfp = Rfp.new(params[:rfp])
if [:payment_gateway][:name]
#pm=PaymentGateway.new([:payment_gateways][:name])
end
as payment gateway is independent model:
Even though paymengt gateway name passing in params it shows above error. What is missing? Please give me any help. Thanks in advance.
I think you dont understand data types.
On first line, you initialized new instance of Rfp class, and then you are trying to retrieve index of nothing, instead of array or hash.
There are two solutions for this.
I noticed that payment_gateways are inside rfp parameters, so i guess its association or attribute of it, so you can check "show me all the names of payment_gateways in newly initialized object"
if #rfp.payment_gateways.map(&:name).any?
Check in params:
if params[:rfp].present? and params[:rfp][:payment_gateways].present? and params[:rfp][:payment_gateways][:name].present?
After that, initialize your PaymentGateway instance:
`#pm = PaymentGateway.new(params[:rfp][:payment_gateways])`
As per your code it should be if params[:rfp][:payment_gateways][:name] not if [:payment_gateway][:name]
So It should look like
as your incomplete params there is rfp as well so it might be params[:rfp][:payment_gateways][:name]
if params[:rfp][:payment_gateways][:name]
#pm=PaymentGateway.new(params[:rfp][:payment_gateways][:name])
end
or inliner
#pm=PaymentGateway.new(params[:rfp][:payment_gateways][:name]) if params[:rfp][:payment_gateways][:name]
In Controller, it should be:
#rfp = Rfp.new(params[:rfp])
if params[:payment_gateway]
#pm=PaymentGateway.new(params[:payment_gateways][:name])
end
or even better
#rfp = Rfp.new(params[:rfp])
#pm=PaymentGateway.new(params[:payment_gateways][:name]) unless params[:payment_gateway].nil?
also check, whether it should be params[:payment_gateway] or params["payment_gateway"].

Rails - find_by column other than "id" results in "null"

Been trying to get this working for the past several hours, I'm probably over looking something quite simple. Basically I have a "posts" model, and one of the columns I have created is named guid, which is just a user definable field that gets saved to the database.
I'm looking to find_by the guid instead of the default id.
Of course I've tried #post = Post.find_by_guid(params[:guid]) in my posts controller show action, but when I attempt to call it from the url (ex: mysite/post/53), in the server console it says guid is NULL
Webrick Console:
Processing by PostsController#show as HTML
Parameters: {"id"=>"53"}
Post Load (0.4ms) SELECT "posts".* FROM "posts" WHERE "posts"."guid" IS NULL LIMIT 1
....
if the route is
get "/posts/:id"
Then you will its the id that is going to be placed in the params which you can see in the output. So use params[:id]
#post = Post.find(params[:id])
You should change your route if you are passing a GUID:
get "posts/:guid" ...
Hit the url "posts/21EC2020-3AEA-1069-A2DD-08002B30309D"
And then in the controller:
#post = Post.find_by guid: params[:guid]
Rails passes instance variables (any variable starting with #) set in the controller to the views.
Referencing instance variables in the view that the controller did not set will return nil, which does not have any of the methods you are going to call on it, hence the "No method" errors.
Any time you run into trouble, check your assumptions at the console. I recommend using Pry. Using Pry (calling "binding.pry" in your code) you can actually stop the execution at any point and look around. That way you never have to guess.
The find_by_[column] method is deprecated.
Use the following syntax: find_by guid: params[:guid]
Your parameters hash does not contain a :guid key. If you were to use mysite/post/53?guid=SOMETHING then you will see a :guid key in params.
Do you want the 53 in this example to be the GUID parameter? There are ways to change the Rails routes to get that parameter to be guid instead of id, but if 53 is the GUID, you can always go:
Post.find(:guid => params[:id]).first

Resources