assign params hash with javascript variable - ruby-on-rails

Is it possible to assign the params hash with javascript variables in the views side.
because i would be doing a complicated structure in my params hash that involves nesting and arrays.

You can post JSON data to the rails server and Rails will make it available in params hash, provided the JSON response data has the correct headers. Refer this thread and this thread for more details.

The only way I can think of is to use JS to add new fields to your form, giving them IDs and names adhering to how Rails will parse the elements' names into params when the form is submitted (something along the lines of id=model_assoc_attributes_N_attr and name=model[assoc_attributes][N][attr], which I think is the case when Model accepts_nested_attributes_for Assoc).

Related

Rails 5 Params / Strong Params issue

I have a RESTful API (ActionController::API) service that accepts a list of params. The RESTful service takes a JSON body request (with Content-Type of application/json). When I debug the controller/action (right after the action def) and take a peak at the params list, it appears as follows:
<ActionController::Parameters {"given_name"=>"Mark", "subdomain"=>"development", "controller"=>"user", "action"=>"create", "user"=>{"given_name"=>"Mark"}} permitted: false>
EDIT
All the request has in it (when it is passed to the controller/action -- using POSTman):
{"given_name":"Mark"}
Notice that the object contains the given_name params twice. Is this normal behavior? I did not pass a "user" object (json object) to the controller/action? What is the permitted flag?
When I try to use (right now I'm just testing RESTful call and assigning any values that the user object will except... no validations have been programmed yet):
user = User.new(params)
I get the error:
#<ActiveModel::ForbiddenAttributesError: ActiveModel::ForbiddenAttributesError>
So, I've looked everywhere for the reasoning behind this (why is there a "user" key in the params list? What is the purpose of the permitted flag? Why am I getting an error when I try to assign params)?
EDIT
After doing some testing, I change the controller name from "user_controller" to "tester_controller" and setup the routes to point to the renamed controller.
It seems the "user" object in the params list above has changed to "tester". So why does the param list contain an "object" with all the passed params with the name of the controller? If that's the case, why is it needed?
Any help would be greatly appreciated.
By default Rails in API mode wraps JSON request parameters into a hash guessing its name from controller class. That's why changing the controller from User to Tester changes "object" name. You can read details here.
So if you don't need this "object" in your params just remove :json from :format array in config\initializers\wrap_parameters.rb. Or you can use fine-grained control at the controller level as described above.
You need to specify which attributes are acceptable for mass-assignment in your controller.
def create
#user = User.new(params.require(:user).permit(:given_name))
end
This prevents malicious users from making request posts that alter attributes internal to your application, like role in the case of a user object.
As mentioned above, a better explanation can be found in the guide referring to strong parameters.
You can't pass params to constructor, because params always contain :action and :controller keys. Attributes for new objects should be put in hash under key that identify model you want to create e.g. :user. I suggest you to consult rails guides, especially chapter 7 of "Form Helpers" guide.
If you want to learn more about strong parameters there is a chapter in rails guides for that too :)

How to access Rails params before all of the values are stringified?

I'd like to be able to inspect the params hash before all of the values are stringified by Rails. For example if I am using application/json Accept/Content-Type, and I receive:
{ "id":1, "post":"Hello" }
I want to be able to know that params[:id] was originally passed as a JSON integer, not a string.
I also want to be able to do this within a controller spec, which uses a limited set of middleware (or none at all?). Is this possible?
I believe this post has what you are looking for: How to access the raw unaltered http POST data in Rails?
request.raw_post
http://api.rubyonrails.org/classes/ActionDispatch/Request.html#method-i-raw_post

What builds nested parameters in Rails?

I am spiking an AngularJS 1.0.8 application, which is doing POST requests to a Rails 3.2.13 server. I did something very similar earlier today with slightly different results.
For the sake of example, the main resource will be Person(name:string).
In the earlier attempt, the submitted attributes for creating a new Person instance were processed by Rails as follows: {"name"=>"John", "person"=>{"name"=>"John"}}
In the later attempt, the submitted attributes were processed as follows: {"name"=>"John", "person"=>{}}
In the outbound request from my browser, the request bodies look identical: {"name":"John"}
I would like to know which part of Rails decides what to use for nested parameters, so that I may figure out why these two implementations seem to differ.
It turns out that the attr_accessor fields on the newer version of the model did not correspond with the fields being sent with the client POST. Those fields are being used by Rails to populate the nested parameters on such a request.
class Person
attr_accessor :name
end
# request body for a POST to /people
{"name":"John","age":"23"}
# request parsed and nested in Rails route
{"name"=>"John", "age"=>"23", "person"=>{"name":"John"}}
My assumption, based on what I have read in related nested-param questions and docs, is that fields and associations on ActiveRecord models are used to decide the structure of nested parameters.

Rejecting extra url parameters from params hash in rails

I am building an API using rails that can take quite a few parameters. Ideally, if the user includes an extra, unnecessary paramater in the request by accident which does not make the request ambiguous I would like to process it as normal. This obviously prevents me from simply writing
ApiRequest.new(params)
since an UnknownAttributeError will be thrown if there is anything extra in the params hash. Is there a simple way of rejecting the extra attributes or will I have to write a method to manually validate the request before creating a new object. Also, would this be considered bad practise for an API, should I be responding with HTTP 400 if this occurs?
Thanks,
Tom
Thanks for the suggestion Sergio, I ended up adding the following initialize method in my ApiRequest class which allows me to mass assign regardless of what is in the hash. If anyone uses this just make sure you ensure attributes are attr_protected if they need to be.
def initialize(params)
params.delete_if {|k| !self.respond_to? "#{k}="}
super
end

RoR: POST to a page using raw form data. How?

Is there a ruby method to POST form data encoded in "x-www-form-urlencoded" as specified here? http://www.w3.org/MarkUp/html-spec/html-spec_8.html
I am aware of Net::HTTP.post_form, but because I have several values to post which share the same name I can't use a hash, which is required by that method.
To clarify, I have a string of the form "value1=x&value1=y&value1=z&value2=a&value3=b" and I want to be able to POST it to another page. How can I do this?
I think internally the params object is a parsed version of the actual raw post body in the http request. All post data is posted the same way (as raw post data), but the params hash in ActionController has already parsed this into an easy-to-use hash. If you actually need the raw post data from a form, you can access it through the raw_post method of the request object itself.
The ActionController::Request.raw_post documentation here is for rails3, but has been available since at least 2.3.8 (the only 2.3.x version I checked). I think it most likely has been available longer than that.
In a controller, try self.request.raw_post to get the raw post data as a string.
Are you able to have a hash value which is an Array? I think that this is the way parameters with the same names are usually handled.

Resources