Vue.js with Rails 6 and Performing CRUD Operations

Akshaykumar Chakkarkota
Jan 30 · 7 min read

In this tutorial, we will study how to setup Vuejs with Rails 6 and perform CRUD operations.

Before we start I will assume that you have installed Ruby (version greater than 2.6.0), Rails 6, NodeJs, and yarn on your machine.

rails new rails_vuejs --webpack=vue

This will install a new project with Vue.js included as a pack. A pack is Rail’s terminology for any JavaScript we add to the project.

Open the project and check for the Javascript pack directory that Rails has generated for us i.e app/javascript/packs/hello_vue.js. Rename this file from hello_vue.js to main.js and include this file using a javascript pack tag in the main layout file i.e app/views/layouts/application.html.erb by copy-paste the content from snippet 1.1 to application.html.erb

snippet 1.1: application.html.erb

Now we create a welcome controller with index action by running the following command

rails generate controller Welcome index

It will create several files. Open the app/views/welcome/index.html.erb delete all of the existing code in the file and keep it empty. This will be our main home page where we display our components, change the index action URL to root in routes.rb file i.e config/routes.rb

root to: 'welcome#index'

Now we create a user controller by running the following command

rails generate controller Users

Add routes in route.rb file as resources :users and for index action in place of using users view page i.e app/views/users/index.html.erb file we need to display Vue component i.e app.vue file. So

resources :users
get 'app', to: 'users#index'

Now start both the servers
Backend server with rails server
Frontend server with bin/webpack-dev-server
and visit http://localhost:3000. You will see a screen as shown in the following image 1.1

image 1.1: Hello Vue

Add Vuetify and its configuration inside the main.js file. To know more about Vuetify visit https://vuetifyjs.com/en/

npm add vuetify

After that, we need to tell Vue to use Vuetify (in most cases, in the main.js file) that’s why we renamed our hello_vue.js to main.js copy-paste content from the below snippet into main.js

snippet 1.2: main.js

Some components are using icons, we added the Google Fonts and Font Awesome links in snippet 1.1 application.html.erb in line no. 8 and 10 in the link tag respectively.

We need to display a table to show data in a proper format. we are using the Vuetify Datatable Components. To know more about these visit following link:

https://vuetifyjs.com/en/components/data-tables#crud-actions

Create a directory named components in the project’s packs directory i.e app/javascript/packs and create a user.vue inside the components directory and copy-paste the vuetify data table component code.

image 1.2: After adding user.vue

Now, import a user component and copy-paste content from snippet 1.3 into app.vue

snippet 1.3: app.vue

Run both the servers and visit http://localhost:3000 and you will see a screen as shown in the following image 1.3

image 1.3: Vuetify Datatable

Note: If Modal is not opening then check the browser console if it shows warning as shown in below image 1.4

image 1.4: Vuetify error

Then check that the entire app is wrapped in <v-app></v-app>. Because in Vuetify you need to wrap your application in <v-app></v-app>. The v-app components set this data-app attribute.

Installing Axios Http Client
Now it’s time to install Axios using the following command:

yarn add axios

Now, import the Axios in the user component and replace the code from snippet 1.4 to user.vue

snippet 1.4: user.vue

It’s time to start with some backend stuff as the current data in our project is static. So, let’s do that.

Add a user model by running the following command

rails g model User first_name:string last_name:string email:string    phone:integer address:string

After that run rails db:migrate
Next, add some data from backend i.e rails console.

Backend Index API

Now we start writing the APIs. We have different endpoints. so, let’s first see /users endpoint

#app/controllers/users_controller.rbdef index
@users = User.all
render json: @users
end

Vue and Axios GET Example
Add the below code as we now get the data from API.

#app/javascript/packs/components/user.vueinitialize() {
return axios
.get("http://localhost:3000/users")
.then(response => {
console.log(response.data);
this.desserts = response.data;
})
.catch(e => {
console.log(e);
});
}

Vuetify Datatable Component has given a Watch property. In this created function is written which is one of the life cycle hooks of Vuejs and It gets called whenever the component gets created. This calls the initialize() method where we are taking the data from the response and then returning a Promise, from the function, which would resolve to an array of users or an error.

If everything is done correctly without any errors then the updated data in the table which came from API request as shown in the following image 1.5

image 1.5: index data from api

We also need a method to show a single user by using id or primary key. Let’s add that method

Backend Show API

#app/controllers/users_controller.rbdef show
@user = User.find(params[:id])
render json: { data: @user, status: :ok, message: 'Success' }
end

Vue and Axios GET Example

#app/javascript/packs/components/user.vuegetUser(item) {
axios.get(`https://localhost:3000/${item.id}`)
.then(response => {
this.dessert = response.data;
})
.catch(error => {
console.log(error);
})
}

In the same way, the method returns a Promise which would resolve to a single user or error.

Backend Update API

#app/controllers/users_controller.rbdef update
@user = User.find(params[:id])
if @user.update(user_params)
render json: { status: :ok, message: 'Success' }
else
render json: { json: @user.errors, status: :unprocessable_entity }
end
end

Vue and Axios Put Example

Let’s see the code for making an HTTP PUT method which can be used to update data.

Before that add the following method in the user component which makes our model open

#app/javascript/packs/components/user.vueeditItem(item) {
this.editedIndex = item.id;
this.editedItem = Object.assign({}, item);
this.dialog = true;
}

There is one variable editedIndex in the data() method of the Vue component which has a predefined value of -1. When we click on the edit icon we are passing an item object to editItem(item) method. There we are checking the editedIndex value with the item object id so that it should always be greater than -1 and we are assigning that item object values to the editedItem which we are using to show that data in the modal and also making the dialog to true.

Now On click of saving, we are calling the save method by passing the editedItem values as the object. i.e save(editedItem). In the user component add the following method:

#app/javascript/packs/components/user.vuesave(item) {
if (this.editedIndex > -1) {
axios
.put(`http://localhost:3000/users/${item.id}`, {
id: this.editedItem.id,
first_name: this.editedItem.first_name,
last_name: this.editedItem.last_name,
email: this.editedItem.email,
phone: this.editedItem.phone,
address: this.editedItem.address
})
.then(response => {
console.log(response);
this.initialize();
})
.catch(error => {
console.log(error);
});
} else {}
this.close();
}

In the save() method, we are checking editedIndex value by using if condition. If the value is greater than -1 then we make a PUT call to the API server by using the Axios.put() method.

Don’t forget to add Strong Parameters in Private method

#app/controllers/users_controller.rbprivate
def user_params
params.require(:user).permit(:id, :first_name, :last_name, :email, :phone,:address)
end

Note: While updating the data you may get this error Can’t verify CSRF token authenticity and data won’t get updated. Just add the below line in ApplicationController i.e app/controllers/application_controlle.rbit will solve the problem.

skip_before_action :verify_authenticity_token

Backend Create API

#app/controllers/user_controller.rbdef create
@user = User.new(user_params)
if @user.save
render json: { status: :ok, message: 'Success' }
else
render json: { json: @user.errors, status: :unprocessable_entity }
end
end

Vue and Axios Post Example

Let’s now see how you can post data to our RESTful API server by sending an HTTP POST call using Axios.
Here we are using the same method save() while updating and creating a record, This time in save() method the condition if becomes false and thus it enters into else part. Add the following method in the user component in the else part of save(item) method

#app/javascript/packs/components/user.vueelse {
axios
.post(`http://localhost:3000/users/`, {
user: this.editedItem
})
.then(response => {
console.log(response);
console.log("Created!");
this.initialize();
})
.catch(error => {
console.log(error);
});
}

The method save(item) takes a user object and sends it via a POST request using Axios.post() method. The function returns a Promise which can be resolved to success or error response.

Backend Delete API

#app/controllers/users_controller.rbdef destroy
@user = User.find(params[:id])
if @user.destroy
render json: { json: 'User was successfully deleted.'}
else
render json: { json: @user.errors, status: :unprocessable_entity }
end
end

Vue and Axios Delete Example
Let’s see how to add a method for deleting a user. Add the following method in the user component

#app/javascript/packs/components/user.vuedeleteItem(item) {
const index = this.desserts.indexOf(item);
confirm("Are you sure you want to delete this item?");
axios
.delete(`http://localhost:3000/users/${item.id}`)
.then(response => {
console.log(response);
console.log(response.data.json);
alert(response.data.json);
this.initialize();
})
.catch(error => {
console.log(error);
});
this.desserts.splice(index, 1);
}

The delete() use the Axios.delete() method to send a DELETE request to the API server.

Conclusion
In this tutorial with Vue and Axios, we’ve seen how to implement CRUD (Create, Read, Update and Delete) functionality using the Axios Http client with Vue.js and Rails 6 as REST API server.

All the source code is available at https://github.com/akshch/rails_vuejs

If you have faced any issue do drop a comment📝 👇 mentioning the issue.

Hit 👏 if you like the article or it helped you in some or the other way. Claps inspire me to write more such articles/tutorials.

More From Medium

Also tagged Vuetify

Claus Straube
Feb 4 · 5 min read

5

Related reads

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade