Reputation: 1375
I'm creating a nested model in Rails, but I want to add fields to the nested models in the controller. I'm not using hidden_field_tag since it could be tampered with.
Here is my params hash:
Parameters: {"dummy"=>{"users_attributes"=>{"0"=>{"email"=>"[email protected]", "id"=>"", "_destroy"=>"false"}, "1"=>{"email"=>"[email protected]", "id"=>"", "_destroy"=>"false"}}}, "commit"=>"Create Dummy"}
What I want is for there to be a field under each user_attributes called companyid. Let's say I wanted companyid to be "company", then I thought that this would work:
len = params["dummy"]["users_attributes"].size
counter = 0
while counter < len
params["dummy"]["users_attributes"][counter]["companyid" => "company"]
counter = counter + 1
end
But, I get "undefined method `[]' for nil:NilClass" error for the first line in the while loop. I'm not exactly sure why.
Can someone help me out so I can modify the params hash?
EDIT: So, I finally figured it out. I didn't really use any of the solutions exactly. First, I set a hidden_field tag to be blank for companyid. Then, in my controller I put:
params["dummy"]["users_attributes"].each do |key, val|
params["dummy"]["users_attributes"][key]["companyid"] = "company"
end
Not the most elegant code, but it'll work.
Upvotes: 6
Views: 7150
Reputation: 14078
The params hash is special since (especially with forms) is it mapped one-for-one with the model(s) it is related to, and Rails expects there to be either a database column, or a method in the model having that name.
Hidden fields are the typical solution to the problem of getting at additional data, but if you don't want users to see those fields, you run into the problem that HTTP is stateless. So in this case, the session[:something]
is your friend. Before displaying a form or page that may have hidden data, instead add the data to a session variable (encrypt it first), which you can then read (and decrypt) when the user submits the form. Or you can save it in a database table and put only the row id in the session so the data can be read back when the form is posted.
If the data was part of the model, but you just didn't want to display it, you could just display the parts the user could see in the view, but then look up the rest of it in the controller action when the user submitted the form or request.
If the data is not sensitive you can just make sure to declare the values that the user can change as attr_accessible
in their respective models (prevents mass assignment) and put the others in hidden fields.
Upvotes: 4
Reputation: 11647
That's not how hashes work. Try this:
params["dummy"]["users_attributes"][counter]["companyid"] = "company"
EDIT In addition to fl00r's answer, yes, you'd have to set ["companyid"] to be {} first.
Upvotes: 0
Reputation: 83680
This looks ugly and I don't understand what is going on, but your mistake is:
len = params["dummy"]["users_attributes"].size
counter = 0
while counter < len
params["dummy"]["users_attributes"][counter] = { "companyid" => "company" }
counter = counter + 1
end
I believe you should use accepts_nested_attributes_for
here and initialize new companies in controller, not this ugly code
Upvotes: 0