Is it possible to update a rails record with vanilla javascript without intercepting the data and converting it to a hash in the controller? Here is my code:
var data = new FormData(); data.append("authenticity_token", csrf_token_value); data.append( "user", JSON.stringify({ name: name, instagram: instagram, employer: employer, home_base_id: homeBase, }) ); fetch(`/${username}/edit`, { method: "PUT", body: data, }) .then((response) => { console.log("response: ", response); }) .catch((error) => { console.log("error: ", error); });
If I just send the data without stringifying it, it shows up in the rails controller at user: [object, object]
. In the update action I update the params like this: params["user"] = JSON.parse(params["user"])
Is there a more straight forward or elegant way to do this?
Advertisement
Answer
If you want to send a application/x-www-form-urlencoded
or multipart/form-data
request then there is no reason to JSON encode the contents.
Just send FormData pairs instead:
let data = new FormData(); data.append("authenticity_token", csrf_token_value); data.append("user[name]", name); data.append("user[instagram]", instagram); data.append("user[employer]", employer); data.append("user[home_base_id]", homeBase); fetch(`/${username}/edit`, { method: "PATCH", body: data, }) .then((response) => { console.log("response: ", response); }) .catch((error) => { console.log("error: ", error); });
Rack will parse key names with non-empty brackets into hashes.
irb(main):002:0> Rack::Utils.parse_nested_query("user[name]=joe&user[employeer]=evilcorp") => {"user"=>{"name"=>"joe", "employeer"=>"evilcorp"}}
I don’t know where you’re going with /${username}/edit
. In Rails conventions you would typically update a user by sending a PATCH /users/:id
request. The new
and edit
actions just render forms. Even if you create a set of vanity urls like this I would still stick to that convention.