This tutorial will cover the steps in adding react.rb and react components (written in Ruby of course) to a simple rails Todo app.
The tutorial is organized as a series of tagged branches in this repo. You are currently on the 01-introduction branch.
In each branch the README file will be the next chapter of the tutorial.
At the end of each chapter you can move to the next tagged branch, where the changes described in the previous chapter will be stored.
For example in this chapter we are going to add the reactive_ruby_generator gem to the app, and use it to install react.rb, reactive-record and reactive-router.
To see the results of these changes you can view the 02-adding-a-react-component chapter.
Of course for best results follow along yourself:
- clone this repo to your computer
- run
bundle install,bundle exec rake db:migrateandbundle exec rake db:test:prepare - follow the instructions for each chapter,
- Then run the test specs for the chapter:
bundle exec rspec spec/chapter-xx.rb -f d
Some chapters (like this one) have extra notes at the end of the page with details you may be interested in.
To update your new or existing Rails 4 app, you can use the reactive_rails_generator gem.
- add
gem 'reactive_rails_generator'to the development section of your app Gemfile. - run
bundle install - run
bundle exec rails g reactrb:install --all - run
bundle update
You will now find that you have
-
a
componentsdirectory inside ofapp/viewswhere your react components (which are simply react views written in ruby) will live, and -
a
publicdirectory inside ofapp/modelswhere any models that you want accessible to your components (which will run on the browser) will live. Don't worry! Access to model data is protected by a Hobo style permissions system.
In our case we are going to make the Todo model public by moving it from app/models to app/models/public/.
If you are following along on your computer run
bundle exec rspec spec/chapter-1.rb -f d
For the next instructions : Chapter 2 - Our first React.rb Component
--reactive-router to install reactive-router
--reactive-record to install reactive-record
--opal-jquery to install opal-jquery in the js application manifest
--all to do all the above
Its recommend to install --all. You can easily remove things later!
In case you are interested, or perhaps want to customize the install here is what happens:
-
It requires
'components'and'react_ujs'at the start of yourapplication.jsfile.componentsis your manifest of react.rb components, andreact_ujsis part of the react-rails prerendering system. -
It adds the js code
Opal.load('components')to the end of theapplication.jsfile. This code will initialize all the ruby (opal) code referenced in thecomponentsmanifest. -
If you are using reactive-record it adds
route "mount ReactiveRecord::Engine => "/rr"to your routes file. This is how reactive record will send and receive active record model updates from the client. Note - you can change the mount path fromrrto whatever you want if necessary. -
It adds the
componentsdirectory toapp/views. This is the directory that all your components will be stored in. -
If you are using reactive-record, then it also adds the
publicdirectory toapp/models. Any models in this directory will have reactive-record proxies loaded on the client. -
It creates the
app/views/components.rbmanifest file. This file is a set of requires for all your ruby component code. The manifest ends with arequire_tree './components'which in most cases should be sufficient to load all your component code from theviews/componentsdirectory. If you have specific component load ordering needs (which is rare) you can simply require specific files before the require_tree. Note - this manifest is loaded both on the client and in the prerendering engine. Code that depends on browser specific data and functions can be conditionally loaded in the manifest so it will not load during prerendering. -
If you are using reactive-record the
components.rbfile will also requireapp/models/_react_public_models.rbwhich is the manifest file for the public models, and simply contains arequire_tree './public'directive. If you need to order how the models are loaded you can add explicit requires to this file before the require_tree. -
It adds these lines to
application.rbconfig.assets.paths << ::Rails.root.join('app', 'views').to_sIf you are using reactive-record it will also addconfig.assets.paths << ::Rails.root.join('app', 'models').to_sconfig.eager_load_paths += %W(#{config.root}/app/models/public)config.autoload_paths += %W(#{config.root}/app/models/public)The effect of these lines is that the asset pipeline can load components from the views folder, and isomorphic models can be found by both the server and asset pipeline in the models/public folder. -
Finally it adds the following gems to your
Gemfile:gem 'reactive-ruby'gem 'react-rails', '~> 1.3.0'gem 'opal-rails', '>= 0.8.1'gem 'therubyracer', platforms: :rubygem 'react-router-rails', '~>0.13.3'(if using reactive-router)gem 'reactive-router'(if using reactive router)gem 'reactive-record'(if using reactive-record)