Skip to content
Advertisement

Updating a rails record with vanilla javascript

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.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement