How to Create a Simple CRUD App With Rails and Vue

This tutorial was inspired by James Hibbard’s post
but instead of using React, I will use Vue. This is not meant to compare
React and Vue nor to conclude which one is better though I find Vue more
approachable. This is just my second time to use Vue so please don’t look
at me as an expert. This is also a learning experience for me and I hope
you learn something, too :)

While most of the content are based on James' post, I decided to treat Rails
and Vue as two separate applications. The Rails application is API-only that
serves JSON, i.e. you will not see any mention of Vue included in the codebase.
On the other hand, the Vue application is also a pure web client and does
everything via API calls. I will also use Vuex to centrally managed the API
calls and the state used by the Vue components.

In this post, I decided not to do a typical tutorial where you go about
building the application from start to finish. Instead, I will just
highlight the major code changes.

I like separating the actions into disctinct methods even though it
often just results to one-liners. However, this clean separation
makes the controller easier to understand and evolve. For example,
event_scope may eventually evolve to scope with current_user.

Our Rail application is boring but I love it that way.
It is all Ruby and there is no Javascript framework to worry about

Since we have built an API on top of Rails, we need to tell our Rails
application that requests would come from a diferent source. Otherwise,
our Vue application will just receive errors every time it calls the API.
If you’re planning on serving your Vue application other than from
localhost, update the origins parameter and restart your Rails application.

Vue Components

Components are building blocks of a Vue-based application. You might
represent the page header as a component, or the sidebar, the list
of events, or even just the event itself. A single page can also
be a component composed of several components, and so on.

Components under src/views, by convention, maps to URLs and
represent the top-level page. The mapping is listed in src/router.js.

In this sequence, the Vue component has no idea about the API
calls - it simply calls a Vuex action. The Vuex action has
no idea about about the Vue component - it only cares about
the API request/response and the state to be modified. The Vue
component reacts to changes to the state.

Vuex and State Management

When building an application, you often how to deal with these three
things:

state - the source of truth

view (or views) - mapping the state for the components

actions - ways the state could change

In our sample application, the state is the list of events,
the view is the component the displays each event, and the
actions are loading the events via the API, adding new event,
etc.

The beauty of Vuex (and other state management libraries like Redux)
is it enables a clean separation between state, views, and actions
and at the same, they work together in a harmonious way. It was
an aha! moment when I finally I understood what it does.

Listing Events

Let’s see how the Vue pieces fit together in the context of listing events.

First, initialize list of events.

// src/main.js#9
const store = initStore({
[states.EVENTS]: []
});

Visiting the URL /events loads the EventsView component.
The mapping is specified using the Vue Router.

The EventForm component handles the saving of events whether it is part
of adding a new event or updating an existing one sequence. The component also
follows the state-view-actions pattern. First, we create a handler
when the form is submitted.

Conclusion

At this point, I hope you have a good idea how the different parts of Vue works
together. Like I said in the beginning, I’m not an expert in Vue nor have I
extensive experience on other Javascript frameworks like React. Though personally,
I find Vue more approachable and I will definitely use this in my personal
projects.

If you are new to Vue (like I am), I highly recommend you read their list
of beginner gotchas. I
guarantee you in will save you lots of frustrations :)