This is a little more advanced example for go-on-rails generator. There's a simple one if you're new to go-on-rails.
The example shows:
- How to use the gems devise, rails_admin and cancancan to implement an admin console to manage a
Post
model - And use the gem go-on-rails to generate Go APIs codes, make an
index
and ashow
web page
The highlight or primary purpose of the example is using Rails as a tool to write
Go web app, and give it an admin console in less than 10 minutes.
Now let's go!
At first we create a Rails project:
rails new example_with_admin --database mysql --skip-bundle
Then we edit Gemfile
to add gems we need:
gem 'go-on-rails', '~> 0.4.0'
gem 'devise'
gem 'rails_admin', '~> 1.2'
gem 'cancancan', '~> 2.0'
then run bundle
.
Because we assume you're familiar with Rails, so below we'll not give too much details on Rails part.
Firstly we will follow the devise
doc to create a user model named User
, and then we run rails_admin
and cancancan
installation also following corresponding steps in their github README doc.
Some points we'll give here are:
- we add a
role
column toUser
model forcancancan
to manage the authorization:
rails g migration add_role_to_users role:string
and then edit the migration file to give it a default value: "guest".
- create a simple
admin?
method inUser
model based the aboverole
column:
def admin?
role == "admin"
end
Now let's create a Post
model:
rails g model Post title content:text user_id:integer
then we edit them as user
has many posts
association.
also we can give Post
model some restrictions, e.g.
# app/models/post.rb
class Post < ApplicationRecord
belongs_to :user
validates :title, presence: true, length: { in: 10..50 }
validates :content, presence: true, length: { minimum: 20 }
end
Then we rails s
to start the server and visit http://localhost:3000/admin
, follow the steps to signup a user, but don't login immediately.
We make the user admin
role in Rails console:
User.first.update role: "admin"
Then we login the rails_admin to create some posts.
Now it's time to show the power of go-on-rails
:
rails g gor dev
Then we go to the generated go_app
directory to make two web pages, an index
page to list all posts, and a show
page to show a post content.
We need to make two template files named index.tmpl
and show.tmpl
under the views
directory at first, and create a controller file named post_controller.go
in controller directory, the controller file have two handler
functions: a IndexHandler
and a ShowHandler
.
We use the Gin
framework, more details you can refer to its doc: https://github.com/gin-gonic/gin.
And at last edit the main.go
to add two router paths to pages:
r.GET("/", c.IndexHandler)
r.GET("/posts/:id", c.ShowHandler)
Run the server(listen the port 4000 by default):
go run main.go
Now you can visit the index
page on: http://localhost:4000.
We'll do next:
- Add CSS to pages
- Paginate post list in
index
page User
authentication in Go app by JWT tokens...
Welcome back and let's go on ...
Now let's make things a little bit complicated, we'll abandon the templates we used above.
Because Rails 5.1 released with a gem webpacker, we'll use it to implement an independent frontend view to call our Go APIs to render an index and a post pages.
We try to make the steps clearer than previous sections due to the necessary details of new techniques.
We can install and configure the webpacker by simply following its README file, but one thing need to mention is to make sure some prerequisites installed before hand. After that we can begin to install webpacker:
# Gemfile
gem 'webpacker', '~> 3.0'
then bundle and install:
bundle
bundle exec rails webpacker:install
Because we plan to use React
in our project, we need to install the React support of webpacker:
bundle exec rails webpacker:install:react
We can see some directories and files generated into the Rails, here the important directory is the app/javascript/packs
, we'll write our react programs all there by default webpacker config.
material-ui is a package of React components that implement Google's Material Design, use it can make some complex and beautiful pages easily. So we'll try it.
And we have a index and a post pages, so we need to make a frontend router for these different views. We use react-router-dom to make it.
Now let's install them by the package tool yarn
(although you can use npm
as well):
yarn add material-ui react-router-dom
Now let's create a controller and a page as a server-side template to integrate the webpacker's helper and React files. If you don't understand this currently, just keep it in mind, I'm sure you'll get it after steps.
rails g controller Pages home
Change the route get 'pages/home'
that Rails added by default in config/routes.rb
to:
root to: 'pages#home'
Edit the view app/views/pages/home.html.erb
, clear all the content of it and add the line below:
<%= javascript_pack_tag 'hello_react' %>
Open another terminal and change to the our project's root directory, run:
./bin/webpack-dev-server
and meanwhile run rails s
in the current terminal, then open http://localhost:3000
in your browser, you can see it prints a "Hello React!". Now we make React and webpacker worked in Rails.
Next let's remove this default installed hello_react
example from our project:
rm app/javascript/packs/hello_react.jsx
We will use another default installed file app/javascript/packs/application.jsx
as our main React programs, so we change the javascript_pack_tag
reference file in our Rails view above from hello_react
to application
:
<%= javascript_pack_tag 'application' %>
then we clear the content of application.jsx
for further programming. And next we will add two more React files as React components corresponding to our index
and show
pages.
Firstly, let's construct the routes for the two views in application.jsx
.
import React from 'react'
import ReactDOM from 'react-dom'
import { HashRouter, Route, Link } from 'react-router-dom'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
import AppBar from 'material-ui/AppBar';
import IndexCard from './index'
import ShowCard from './show'
// some routes
<Route exact path="/" component={Index}/>
<Route path="/posts/:id" component={Show}/>
Here we use HashRouter
instead of Router
directive because we need the server-side render at first, /path
will be an invalid route for Rails while /#path
will be manipulated by frontend.
And we'll created three React components to get the job done:
you can check the files to get the details.
Here we use a javascript package named axios
to do Ajax requests, you can install it by yarn:
yarn add axios
Now when we set up the Rails server to request APIs of our Go application, we need to add a CORS configuration to the Go server to make cross domains accessible. Because we use the Gin framework by default, we choose a cors package specially for the Gin: github.com/gin-contrib/cors.
We just use its default configuration that allows all the Origins access our Go server for testing easily, here's the details.
In one terminal you set up the Go server under the go_app
directory:
go run main.go
In another terminal run rails s
to set up the Rails server in default port 3000, and meanwhile to get the ./bin/webpack-dev-server
server up in a third terminal.
Now visit the http://localhost:3000, you can see our new pages.
(WIP)