Simple Web App with Rails, Webpacker, React, Graphql and ActiveStorage — Part 1

Joseph Mutuku
6 min readFeb 26, 2019

A few weeks ago, my friend and I decided to challenge ourselves and build a rails application using Webpacker and Graphql. These are pretty much new technologies and not very many people seem to have built their applications with this combination. We found ourselves hopping from tutorial to tutorial but each was either lacking two or more of the technologies we were using. We, therefore, had to stitch together ideas from different blogs/tutorials and docs. I then decided to write this blog/tutorial to reinforce my understanding as well as help anyone out there who might be struggling. In this tutorial, I assume you have a basic understanding of how Rails, and React work. Prior experience with Graphql is not necessary but obviously advantageous. Here is a good resource for graphql beginners with rails.

In this project, we will attempt to build a simple app where a client can post an image of a book, its author and an accompanying review. We’ll split it into two parts. Part 2 is where I will introduce file uploads and ActiveStorage.

Prerequisites

I used the following

  • Ruby 2.5.3
  • Rails 5.2.2
  • Node 11.9.0

1. Set up a rails application

We need to set up a rails app first. We provide a few options to disregard tests(TDD is VERY important however I will not be focusing on tests for this project), select database(Postgresql) and to use webpacker with the react option. You may choose to separate the API and the front-end i.e Build a separate react app and then use the API option to build the rails app. That’s still okay but here I will use a monolith application.

$ rails new rails-react-graphql -T -d=postgresql --webpack=react
$ cd rails-react-graphql
$ rails db:create

Install the graphql gem by adding it to your GemFile. By default, the generator adds the graphiql-rails gem to the gemfile.

gem 'graphql', '~> 1.9', '>= 1.9.3'

Once done run the following commands on your terminal to install graphql. The generator shall generate a controller to handle all graphql requests and add a graphql folder under app which shall contain all graphql types/mutation and resolvers

$ bundle install$ rails generate graphql:install $ bundle install # to install graphiql-rails

At this point, you can start up the rails server and navigate to the endpoint /graphiql. Here you will see the graphql IDE engine.

2. Graphql Objects — Type

Before we get into graphql let’s generate our models. We will have one model for Book and it has several fields: title, author, review, reviewer. In a more comprehensive app, you would need to have a way to authenticate users and probably would be better to have relationships between users-books and reviews. For demonstration purposes, we shall just use this simple model. So let’s generate it and run the migration. Missing in the list of fields is the image. However, we shall come back to this in part 2.

$ rails g model book title:string author:string review:text reviewer:string
$ rails db:migrate

We use generators provided by the graphql gem to generate object types. Object types in graphql expose data and can be queried. We want to be able to send a query and get the data we defined like this

# an example of a query
book {
title
author
}
# The above query could return
{
"data": {
"book": {
"title": "A Brief History of Time"
"author": "Stephen Hawking"
}
}
}

To generate the type we run:

$ rails g graphql:object book

This should generate this file which we modify to add a field id, which we know will always exist so we set it’s null to false. We can also modify the title field to be non-nullable.

Next, we create two queries that will map to fetching a single book or all books.

To allow for rapid testing, let’s seed some data in the database by adding editing db/seeds.rb to

Ensure server is on and navigate to /graphiql you then enter the following query and see if the results match. Notice though in query_type.rb we defined the field as all_books we pass the query as allBooks , this is because GraphQL camelizes fields by default.

Get All Books Graphql query
Get a Single Book Graphql Query

GraphQl Mutations

Mutations are used to modify data. This means they can be used either to create or update records. We are going to create a mutation once more by using the graphql generators

$ rails g graphql:mutation CreateBook

Now modify the generated files as follows

Try running a mutation like the one shown below

Setting Up React in Rails and Apollo

Our Rails App has only one useful controller to handle the user requests the graphql controller, and it has one action “execute” which only handles POST requests. Our react app will utilize Apollo Client to send graphql Queries and Mutations. You can introduce yourself to Apollo Client in their docs. The react app we set up here will be wrapped in Apollo so that we can utilise Apollo Client to send GraphQl requests(this should be fun).

We need to generate a controller, let’s call it index_controller, this should render the index view on which our react application can be rendered. This will require a number of steps.

  1. Generate the index controller, then set the index action as the root route in config/routes
$ rails g controller index index

2. Edit the application.html.erb to

3. We build the react components responsible for rendering the form for the user to fill book details. First, let’s add Apollo to our node-modules using our package manager yarn.

$ yarn add apollo-boost react-apollo graphql-tag

Create a folder inside app/javascripts/packs called front-end-react, here is where our react application will reside. Add subfolders, assets/stylesheets and src as well as our entry file to the application App.jsx . If you have built a react application before the following files should look familiar. I have also focused on the mutation part. You should be able to easily replicate the process and build a component to display allBooks and even display a single book when selected. In the repository provided at the end of this tutorial, a component to list all books has been implemented and routing fixed

x

4. We need to tell the views where to find the javascript files as well as stylesheets, that is the entry points for both jsx or scss files

If you access your root path you should be able to see a basic form. I’d recommend using React Dev Tools and Apollo extensions to play around with the application. Here is a screenshot of what I have at this stage, it’s not pretty but functional. Try submitting details and confirm that the database is updated.

We are halfway there, I realize this might be a lot for a first-timer. This is, therefore, the end of part 1. In part 2 we’ll explore how to perform file uploads using react apollo and storing those uploads using ActiveStorage. I hope you have had a good experience so far. See you around.

PS: The complete code can be found at https://github.com/thoth-ky/rails-react-graphql. Feel free to provide feedback.

--

--