Rails and FormData

eyecatch.jpg Rails and FormData

Articles about Rails and FormData. I write both in English and Japanese.

This post talks about using WebAPI's FormData with Rails.

Recently, I replaced Rails Form with an API-based system. In other words, instead of Form, I worked with the backend with an XHR request (axios).

We recently migrated from using Rails formstoanAPIbasedappwheredataissenttothebackendusingXHRrequests(inourcase,usingaxios).

This article uses a typical user model.

For the following example I will be using a generic User model.

Problem ・ Problem

Using Rails Form ・ Using Rails Form

<%= form_for @user, url: {action: "create"} do |f| %>
  <%= f.text_field :name %> # "Yokoyama"
  <%= f.text_field :role %> # "Developer"
  <%= f.submit "Create" %>
<% end %>

If you use Rails Form, you will find the following params in the controller.

If we were using Rails forms then we'd normally get:

def create
 # params = <ActionController::Parameters
 # {
 #  "user" => {
 #    "name"=>"Yokoyama",
 #	  "role"=>"Developer"
 #  },
 #	"controller"=>"...",
 #	"action"=>"create",
 # }
 # permitted: false>
  ...
end

Using FormData ・ Using FormData

When I made the request body, I used FormData.

When packaging a body for a POST/PATCH request we used FormData.


const formData = new FormData();

formData.append('name','Yokoyama');
formData.append('role','Developer');

const url = 'user create link';
axios.post(url, formData, {
            headers: {
              'content-type': 'multipart/form-data',
            },
          })
...
    

The Rails Controller has the following response.

On the Rails backend we get:

def create
 # params = <ActionController::Parameters
 # {
 #  "name"=>"Yokoyama",
 #	"role"=>"Developer",
 #	"controller"=>"...",
 #	"action"=>"create",
 # }
 # permitted: false>
  ...
end

Key Point: --Because the attributes are top-level, problems with the same name can occur. --It's not a Rails pattern.

As you can see:

Solution / Solution

Originally written by @jugtuttle on Medium, but with the model name as the key If it is included, it is a success.

@jugtuttle on Medium pointed out that you can simply use a key that has the model name. So in our case:

const formData = new FormData();

formData.append('user[name]','Yokoyama');
formData.append('user[role]','Developer');

axios.post('insert user path here', formData, {
            headers: {
              'content-type': 'multipart/form-data',
            },
          })
...
    

To make it easier:

To make it even easier:


// rails_form_data.js

class RailsFormData extends FormData {
  constructor(model) {
    super();
    this.model = model;
  }

  append(key, value) {
    super.append(`${this.model}[${key}]`, value);
  }
}

export default RailsFormData;
import RailsFormData from '...'

const formData = new RailsFormData('user');

formData.append('name','Yokoyama');
formData.append('role','Developer');

axios.post('insert user path here', formData, {
            headers: {
              'content-type': 'multipart/form-data',
            },
          })
...
    

Result / Result

The Rails controller has the following states:

Then on the Rails backend side you'll get:

def create
  #  params = <ActionController::Parameters
  #  {
  #    "user" => {
  #      "name"=>"Yokoyama",
  #	     "role"=>"Developer"
  #    },
  #	   "controller"=>"...",
  #	   "action"=>"create",
  # }
  # permitted: false>
  ...
end

Recommended Posts

Rails and FormData
Rails valid? And invalid?
[Rails] N + 1 problems and countermeasures
Rails: Difference between resources and resources
Rails Posts and User Linkage
[Rails] require method and permit method
Rails "render method" and "redirect method"
Rails Tutorial Records and Memorandum # 0
rails path and url methods
Rails is difficult and painful!
Introducing Bootstrap and Font-Awesome (Rails)
Rails is difficult and painful! Ⅱ
[Rails] strftime this and that
Rails web server and application server
[Rails] Save start time and end time
Enable jQuery and Bootstrap in Rails 6 (Rails 6)
[Rails] Difference between find and find_by
[Rails] Validation settings and Japanese localization
Rails model and table naming conventions
Remove "assets" and "turbolinks" in "Rails6".
CRUD features and MVC in Rails
[Rails] Differences and usage of each_with_index and each.with_index
Project ruby and rails version upgrade
Consideration about Rails and Clean Architecture
[rails] Difference between redirect_to and render
[Rails g.error]
Rails basics
Rails Review 1
[Rails] first_or_initialize
Install Webpacker and Yarn to run Rails
rails tutorial
Building Rails 6 and PostgreSQL environment with Docker
== and equals
About Rails 6
Rails Addition of easy and easy login function
Rails foundation
Rails memorandum
rails tutorial
rails tutorial
rails tutorial
[Rails] [Memo] When to add = to <%%> and when not
[rails s error] md5.bundle and mysql installation error
[Rails] devise
Rails migration column changes and so on.
rails tutorial
rails tutorial
Rails Tips
rails method
rails tutorial
Rails validation and null: false Personal notes
[Rails] ActiveRecord
[Rails] Difference between redirect_to and render [Beginner]
[Rails] form_with
Rails Review 2
[Rails / ActiveRecord] About the difference between create and create!
(Basic authentication) environment variables in rails and Docker
Ruby on Rails ~ Basics of MVC and Router ~
[Nuxt / Rails] POST implementation using axios and devise_token_auth
This and that of conditional branching of rails development
Difference between member and collection of rails routes.rb
Rails development environment created with VSCode and devcontainer