DEV Community

loading...
Cover image for How to set up React.js with a Ruby on Rails Project

How to set up React.js with a Ruby on Rails Project

Josh Lee
Updated on ・4 min read

Ruby on Rails is such a wonderful framework to work with. However, using Embedded Ruby (.erb) and ajax to build apps with dynamic frontends can be painful.

And that's where front-end frameworks like React, Angular, and Ember come in. Since React is the hot thing right now, we're going to use it.

But how do you get React.js set up in a Ruby on Rails application? That's what I'm covering in this article

The first thing you need to do is create your Ruby on Rails application and tell it you're going to use React. To do so type the following code:

rails new react-rails --database=postgresql --webpack=react
Enter fullscreen mode Exit fullscreen mode

I’m also using Postgres as the database in this application.

Now that we have the project set up, we need to add a bit of code so our app knows to use React as the front end.

Let’s go to our routes file at config/routes.rb.

You’re going to do something a little bit different with your routes here. You’re going to wrap all of your calls to your backend in an api namespace.

In this project, we’re going to have a model of Posts. So you’d write your routes like this:

Rails.application.routes.draw do
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html

  root 'pages#index'

  namespace :api do
    namespace :v1 do
      resources :posts
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

I also added a root route that goes to our pages controller. When making your backend calls to access your controllers, you’re going to have paths such as ‘/api/v1/posts’ to get your posts.

Now we need to tell our app to send other routes to our main React App. We’ll add this to the bottom of our routes file:

get '*path', to: 'pages#index', via: :all
Enter fullscreen mode Exit fullscreen mode

Your file routes file should look like the following:

Rails.application.routes.draw do
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html

  root 'pages#index'

  namespace :api do
    namespace :v1 do
      resources :posts
    end
  end

  get '*path', to: 'pages#index', via: :all

end
Enter fullscreen mode Exit fullscreen mode

Let’s set up our index.jsx file.

Go to app/javascript/packs/hello_react.jsx and rename name that file to index.jsx. Delete most of the stuff there and make the file look like this.

import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Route } from 'react-router-dom'
import App from '../src/components/App'

document.addEventListener('DOMContentLoaded', () => {
  ReactDOM.render(
    <Router>
      <Route path="/" component={App}/>
    </Router>,
    document.body.appendChild(document.createElement('div')),
  )
})
Enter fullscreen mode Exit fullscreen mode

If you’ve worked with React before, this should look familiar. We’re importing React, ReactDom, and ReactRouterDom. We’re then importing our main App. Then, we create a node in the DOM and insert our app.

Before we forget, let’s add react-router-dom using Yarn. go to your terminal and type:

yarn add react-router-dom
Enter fullscreen mode Exit fullscreen mode

We’re almost to the point where we can see our app in our front end. Let’s go set up our App.js file.

Create the file “app/javascript/src/components/App.js”. We’re going to get our root path to display our posts. In a “regular rails app” this would be the index page in our posts view folder.

Anyway, here’s what the App.js file should look like:

import React from 'react'
import { Route, Switch } from 'react-router-dom'
import Posts from '../components/Posts/Posts'

const App = () => {
  return (
    <Switch>
      <Route exact path="/" component={Posts} />
    </Switch>>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

Let’s make that Posts page in “app/javascript/src/componenets/Posts/Posts.js”. Here’s what mine looks like.

import React from 'react'

const Posts = () => {
  return (
    <div>
      <h1>Posts</h1>
      <p>This is our posts page.</p>
    </div>
  )
}

export default Posts
Enter fullscreen mode Exit fullscreen mode

Now, we need to tell our view to render our React app. Go to “app/views/layout/application.html.erb” and add the following tag:

<%= javascript_pack_tag 'index' %>
Enter fullscreen mode Exit fullscreen mode

Your layout file should look like the following:

<!DOCTYPE html>
<html>
  <head>
    <title>ReactRails</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'index' %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Here, I was about to start my server, but I ran into an “ActiveRecord::ConnectionEstablished” no password supplied error because I did not set up database password in “config.database.yml” so make sure to set up your database settings.

I also had to run rails db:create to create my database

Setting up Postgresql with Rails is out of the scope of this tutorial, sorry!

One more step! We have to set up our PagesController and its view.

Go create a PagesController in “app/controllers/pages_controller”. We just need an index action.

class PagesController < ApplicationController
  def index

  end
end
Enter fullscreen mode Exit fullscreen mode

And your view file in “app/views/pages/index.html.erb”. My file is a blank file since we’re just loading the layout.

Now run ‘rails s’ and you should see the following:

No alt text provided for this image
Now we have React set up on our Rails app. Congratulations, this is a big step!

Stay tuned for connecting the front end to the back end and adding Redux.

If you want to learn more about web development, make sure to follow me on Twitter.

Discussion (3)

Collapse
m_ahmad profile image
Muhammad Ahmad

In my opinion, better approach is creating separate applications for front-end and back-end.

Collapse
jleewebdev profile image
Josh Lee Author

I've done that with a MERN app and it just gave me twice the headaches when deploying.

Collapse
m_ahmad profile image
Muhammad Ahmad • Edited

I agree with that. First time it took me more than 10 days to solve issues while deployment.
But separate apps gave you more control and freedom to handle things differently.
e.g. You can use chakraUI or ant-design etc easily on front-end but when you are using single rails app then it is not possible.