Skip to content

Commit bbffbd5

Browse files
committed
* use cancancan to define abilities
* use rails_admin as a simple admin backend * remove api only for project because we want to access it by rails_admin * add annotate gem * Add basic assets to handle login/password reset and rails_admin * use devise default views to get into rails_admin area
1 parent 1c07e2c commit bbffbd5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1251
-59
lines changed

Gemfile

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,12 @@ gem 'bcrypt', '~> 3.1.7' # Use ActiveModel has_secure_passwor
1515
gem 'devise' # Use devise as authentication module
1616
gem 'graphql'
1717
gem 'graphql-auth', git: '[email protected]:simonfranzen/graphql-auth.git', branch: 'rails6'
18-
gem 'graphql-errors'
19-
gem 'rack-cors'
18+
gem 'graphql-errors' # GrapqhQL error handling
19+
gem 'rack-cors' # Rack CORS settings
20+
gem 'rails_admin', '~> 2.0.2' # Admin interface
21+
gem 'cancancan' # Defining abilities
22+
gem 'image_processing', '~> 1.2' # Image processing
23+
gem 'mini_magick' # Image manipulation with rmagick
2024

2125
# gem 'graphiql-rails', group: :development
2226

@@ -61,6 +65,7 @@ group :test do
6165
end
6266

6367
group :development do
68+
gem 'annotate'
6469
gem 'listen', '>= 3.0.5', '< 3.2'
6570
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
6671
gem 'rubocop-performance' # speed up rubocop

Gemfile.lock

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ GEM
5353
globalid (>= 0.3.6)
5454
activemodel (6.0.3.3)
5555
activesupport (= 6.0.3.3)
56+
activemodel-serializers-xml (1.0.2)
57+
activemodel (> 5.x)
58+
activesupport (> 5.x)
59+
builder (~> 3.1)
5660
activerecord (6.0.3.3)
5761
activemodel (= 6.0.3.3)
5862
activesupport (= 6.0.3.3)
@@ -67,13 +71,17 @@ GEM
6771
minitest (~> 5.1)
6872
tzinfo (~> 1.1)
6973
zeitwerk (~> 2.2, >= 2.2.2)
74+
annotate (3.1.1)
75+
activerecord (>= 3.2, < 7.0)
76+
rake (>= 10.4, < 14.0)
7077
ast (2.4.1)
7178
awesome_print (1.8.0)
7279
bcrypt (3.1.13)
7380
bootsnap (1.4.4)
7481
msgpack (~> 1.0)
7582
builder (3.2.4)
7683
byebug (11.0.1)
84+
cancancan (3.1.0)
7785
concurrent-ruby (1.1.7)
7886
crass (1.0.6)
7987
database_cleaner (1.7.0)
@@ -109,10 +117,34 @@ GEM
109117
graphql (1.9.6)
110118
graphql-errors (0.3.0)
111119
graphql (>= 1.6.0, < 2)
120+
haml (5.1.2)
121+
temple (>= 0.8.0)
122+
tilt
112123
i18n (1.8.5)
113124
concurrent-ruby (~> 1.0)
125+
image_processing (1.11.0)
126+
mini_magick (>= 4.9.5, < 5)
127+
ruby-vips (>= 2.0.17, < 3)
128+
jquery-rails (4.4.0)
129+
rails-dom-testing (>= 1, < 3)
130+
railties (>= 4.2.0)
131+
thor (>= 0.14, < 2.0)
132+
jquery-ui-rails (6.0.1)
133+
railties (>= 3.2.16)
114134
json (2.3.1)
115135
jwt (2.2.1)
136+
kaminari (1.2.1)
137+
activesupport (>= 4.1.0)
138+
kaminari-actionview (= 1.2.1)
139+
kaminari-activerecord (= 1.2.1)
140+
kaminari-core (= 1.2.1)
141+
kaminari-actionview (1.2.1)
142+
actionview
143+
kaminari-core (= 1.2.1)
144+
kaminari-activerecord (1.2.1)
145+
activerecord
146+
kaminari-core (= 1.2.1)
147+
kaminari-core (1.2.1)
116148
listen (3.1.5)
117149
rb-fsevent (~> 0.9, >= 0.9.4)
118150
rb-inotify (~> 0.9, >= 0.9.7)
@@ -126,10 +158,12 @@ GEM
126158
mimemagic (~> 0.3.2)
127159
method_source (1.0.0)
128160
mimemagic (0.3.5)
161+
mini_magick (4.10.1)
129162
mini_mime (1.0.2)
130163
mini_portile2 (2.4.0)
131164
minitest (5.14.2)
132165
msgpack (1.3.0)
166+
nested_form (0.3.2)
133167
nio4r (2.5.3)
134168
nokogiri (1.10.10)
135169
mini_portile2 (~> 2.4.0)
@@ -145,6 +179,9 @@ GEM
145179
rack (2.2.3)
146180
rack-cors (1.0.5)
147181
rack (>= 1.6.0)
182+
rack-pjax (1.1.0)
183+
nokogiri (~> 1.5)
184+
rack (>= 1.1)
148185
rack-test (1.1.0)
149186
rack (>= 1.0, < 3)
150187
rails (6.0.3.3)
@@ -171,6 +208,18 @@ GEM
171208
nokogiri (>= 1.6)
172209
rails-html-sanitizer (1.3.0)
173210
loofah (~> 2.3)
211+
rails_admin (2.0.2)
212+
activemodel-serializers-xml (>= 1.0)
213+
builder (~> 3.1)
214+
haml (>= 4.0, < 6)
215+
jquery-rails (>= 3.0, < 5)
216+
jquery-ui-rails (>= 5.0, < 7)
217+
kaminari (>= 0.14, < 2.0)
218+
nested_form (~> 0.3)
219+
rack-pjax (>= 0.7)
220+
rails (>= 5.0, < 7)
221+
remotipart (~> 1.3)
222+
sassc-rails (>= 1.3, < 3)
174223
railties (6.0.3.3)
175224
actionpack (= 6.0.3.3)
176225
activesupport (= 6.0.3.3)
@@ -183,6 +232,7 @@ GEM
183232
rb-inotify (0.10.0)
184233
ffi (~> 1.0)
185234
regexp_parser (1.7.1)
235+
remotipart (1.4.4)
186236
responders (3.0.0)
187237
actionpack (>= 5.0)
188238
railties (>= 5.0)
@@ -224,7 +274,17 @@ GEM
224274
rubocop-rspec (1.43.2)
225275
rubocop (~> 0.87)
226276
ruby-progressbar (1.10.1)
277+
ruby-vips (2.0.17)
278+
ffi (~> 1.9)
227279
ruby_dep (1.5.0)
280+
sassc (2.4.0)
281+
ffi (~> 1.9)
282+
sassc-rails (2.1.2)
283+
railties (>= 4.0.0)
284+
sassc (>= 2.0)
285+
sprockets (> 3.0)
286+
sprockets-rails
287+
tilt
228288
shoulda-matchers (4.0.0.rc1)
229289
activesupport (>= 4.2.0)
230290
simplecov (0.16.1)
@@ -248,8 +308,10 @@ GEM
248308
unicode-display_width (~> 1.5)
249309
unicode_utils (~> 1.4)
250310
strings-ansi (0.1.0)
311+
temple (0.8.2)
251312
thor (0.20.3)
252313
thread_safe (0.3.6)
314+
tilt (2.0.10)
253315
tty-color (0.5.0)
254316
tty-pager (0.12.1)
255317
strings (~> 0.1.4)
@@ -273,10 +335,12 @@ PLATFORMS
273335
ruby
274336

275337
DEPENDENCIES
338+
annotate
276339
awesome_print
277340
bcrypt (~> 3.1.7)
278341
bootsnap (>= 1.1.0)
279342
byebug
343+
cancancan
280344
database_cleaner (~> 1.6)
281345
devise
282346
dotenv-rails
@@ -285,12 +349,15 @@ DEPENDENCIES
285349
graphql
286350
graphql-auth!
287351
graphql-errors
352+
image_processing (~> 1.2)
288353
listen (>= 3.0.5, < 3.2)
354+
mini_magick
289355
pg
290356
puma (~> 3.12)
291357
rack-cors
292358
rails (~> 6.0.3)
293359
rails-controller-testing
360+
rails_admin (~> 2.0.2)
294361
rspec-rails (~> 3.8)
295362
rubocop
296363
rubocop-performance

README.md

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# Rails 6 API-only boilerplate with devise & JWT & graphQL
1+
# Rails 6 boilerplate with devise, JWT, graphQL, CanCanCan and RailsAdmin.
22

3-
This is a boilerplate to build your next SaaS product. It's a RubyOnRails 6 API only backend with Authentication and GraphQL API. It works nicely together with clients made with **React.js & React.Native** or any other frontend which implements the [JSON Web Tokens](https://jwt.io/introduction/) philosophy. We have a demo frontend made with [gatsbyJS](https://www.gatsbyjs.org/) available here: <https://gatsby-redux.zauberware.com/>.
3+
This is a boilerplate to build your next SaaS product. It's a RubyOnRails 6 backend with Authentication and GraphQL API. It works nicely together with clients made with **React.js & React.Native** or any other frontend which implements the [JSON Web Tokens](https://jwt.io/introduction/) philosophy.
44

55
## Versions
66

@@ -9,6 +9,22 @@ This is a boilerplate to build your next SaaS product. It's a RubyOnRails 6 API
99
- Rails version `6.0.X`
1010
- Postgresql Server as db connector
1111

12+
## Dependencies
13+
This boilerplate works like a charm with the following gems:
14+
- pg
15+
- devise
16+
- graphql
17+
- graphql-auth
18+
- graphql-errors
19+
- rack-cors
20+
- rails_admin
21+
- cancancan
22+
- image_processing
23+
- mini_magick
24+
- puma
25+
- bootsnap
26+
27+
1228
## Quick start
1329

1430
[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/zauberware/rails-devise-graphql)
@@ -60,7 +76,7 @@ Point the GraphQL IDE to `http://0.0.0.0:3000/graphql`
6076
The app uses a postgresql database. It implements the connector with the gem `pg`. The app already includes a `User` model with basic setup.
6177

6278
### 2. Authentication
63-
The app uses [devise](https://github.com/plataformatec/devise)'s logic for authentication. Emails are currently disabled in the environment settings.
79+
The app uses [devise](https://github.com/plataformatec/devise)'s logic for authentication. For graphQL API we use the JWT token, but to access the rails_admin backend we use standard devise views, but registration is excluded.
6480

6581
### 3. JSON Web Token
6682
[graphql-auth](https://github.com/o2web/graphql-auth) is a graphql/devise extension which uses JWT tokens for user authentication. It follows [secure by default](https://en.wikipedia.org/wiki/Secure_by_default) principle.
@@ -74,18 +90,47 @@ Protect your app and only allow specific domains to access your API. Set `CLIENT
7490
### 6. App server
7591
The app uses [Puma](https://github.com/puma/puma) as the web serber. It is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for Ruby/Rack applications in development and production.
7692

77-
### 7. Testing
93+
### 7. UUID
94+
The app uses UUID as ids for active record entries in the database. If you want to know more about using uuid instead of integers read this [article by pawelurbanek.com](https://pawelurbanek.com/uuid-order-rails).
95+
96+
### 8. Automatic model annotation
97+
Annotates Rails/ActiveRecord Models, routes, fixtures, and others based on the database schema. See [annotate_models gem](https://github.com/ctran/annotate_models).
98+
99+
### 9. Abilities with CanCanCan
100+
[CanCanCan](https://github.com/CanCanCommunity/cancancan) is an authorization library for Ruby and Ruby on Rails which restricts what resources a given user is allowed to access. We combine this gem with a `role` field defined on user model.
101+
102+
### 10. Rails Admin
103+
To access the data of your application you can access the [rails_admin](https://github.com/sferik/rails_admin) dashboard under route `/admin`. It's currently only allowed for users with role superadmin.
104+
105+
If you want to give your admin interface a custom branding you can override sass variables or write your own css under `app/assets/stylesheets/rails_admin/custom`.
106+
107+
### 11. Testing
78108

79109
We are using the wonderful framework [rspec](https://github.com/rspec/rspec). The testsuit also uses [factory_bot_rails](https://github.com/thoughtbot/factory_bot_rails) for fixtures.
80110

81111
Run `rspec spec`
82112

83-
### 8. Linter with Rubocop
113+
#### FactoryBot
114+
To create mock data in your tests we are using [factory_bot](https://github.com/thoughtbot/factory_bot). The gem is fixtures replacement with a straightforward definition syntax, support for multiple build strategies (saved instances, unsaved instances, attribute hashes, and stubbed objects), and support for multiple factories for the same class (user, admin_user, and so on), includéng factory inheritance.
115+
116+
#### Faker
117+
Create fake data easily with [faker gem](https://github.com/faker-ruby/faker). Caution: The created data is not uniq by default.
118+
119+
#### Shoulda Matchers
120+
[Shoulda Matchers](https://github.com/thoughtbot/shoulda-matchers) provides RSpec- and Minitest-compatible one-liners to test common Rails functionality that, if written by hand, would be much longer, more complex, and error-prone.
121+
122+
#### Simplecov
123+
[SimpleCov](https://github.com/simplecov-ruby/simplecov) is a code coverage analysis tool for Ruby. It uses Ruby's built-in Coverage library to gather code coverage data, but makes processing its results much easier by providing a clean API to filter, group, merge, format, and display those results, giving you a complete code coverage suite that can be set up with just a couple lines of code.
124+
125+
Access results with `$ open /coverage/index.html`.
126+
127+
128+
### 12. Linter with Rubocop
84129

85130
We are using the wonderful [rubocop](https://github.com/rubocop-hq/rubocop-rails) to lint and autofix the code. Install the rubocop VSCode extension to get best experience during development.
86131

87132

88-
### 9. Deployment
133+
### 13. Deployment
89134
The project runs on every webhoster with ruby installed. The only dependency is a PostgreSQL database. Create a block `production:` in the`config/database.yml` for your connection.
90135

91136
#### Heroku
@@ -102,17 +147,9 @@ If you want to use [bitbucket pipelines](https://bitbucket.org/product/de/featur
102147

103148
Make sure to set ENV vars `$HEROKU_API_KEY` and `$HEROKU_APP_NAME` in bitbuckets pipeline settings. (Will appear after enabling pipelines for your project.)
104149

105-
The pipeline has 2 environments: staging and production. Staging pipline is getting triggered in `develop` branch. Production uses all `release-*` branches.
106-
107-
108-
### 9. Frontend
109-
110-
#### GatsbyJS
111-
112-
If you need a frontend than have a look at this basic [Gatsby boilerplate](https://github.com/zauberware/gatsby-starter-redux-saas). A Gatsby Redux SaaS starter for your next SaaS product. Uses react-redux, apollo-client, magicsoup.io, styled-components, styled-system.
113-
114-
![zauberware technologies](https://github.com/zauberware/gatsby-starter-redux-saas/raw/master/static/website-preview.jpg)
150+
The pipeline has 2 environments: staging and production. Staging pipline is getting triggered in `develop` branch. Production deploy triggered by `master` branch.
115151

152+
It also triggers pipeline when opening a PR.
116153

117154
## What's missing?
118155

app/assets/config/manifest.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
//= link_tree ../images
2+
//= link_directory ../javascripts .js
3+
//= link_directory ../stylesheets .css

app/assets/images/logo.svg

Lines changed: 1 addition & 0 deletions
Loading

app/assets/javascripts/.keep

Whitespace-only changes.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* This is a manifest file that'll be compiled into application.css, which will include all the files
3+
* listed below.
4+
*
5+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7+
*
8+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
9+
* compiled file so the styles you add here take precedence over styles defined in any styles
10+
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11+
* file per style scope.
12+
*
13+
*= require frontend/normalize
14+
*= require frontend/util
15+
*= require frontend/typo
16+
*= require frontend/main
17+
*= require frontend/auth
18+
*= require_self
19+
*/
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//
2+
/* SETTINGS ===================================================== */
3+
/* Global variables, anything that is global for the project ==== */
4+
$color--border: rgb(203, 219, 238);
5+
6+
$gray-base: #080604;
7+
$gray-darker: #221710; // #222
8+
$gray-dark: #3f2b1e; // #333
9+
$gray: #3d6372; // #555
10+
$gray-light: #859fb8; // #999
11+
$gray-lighter: #eaeff5; // #eee
12+
13+
$brand-info: #80bcdc; // default $brand-primary
14+
$brand-success: #c9db8a;
15+
$brand-primary: #0079ba; // default $brand-info
16+
$brand-warning: #e1c345;
17+
$brand-danger: #e5734b;
18+
19+
20+
21+
$font-family-sans-serif: "Roboto",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue",Arial,sans-serif;
22+
$font-family-serif: "Roboto Slab",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
23+
//** Default monospace fonts for `<code>`, `<kbd>`, and `<pre>`.
24+
$font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace;
25+
$font-family-base: $font-family-sans-serif;
26+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@import "_vars";
2+
3+
.authWrapper{
4+
width: 100%;
5+
max-width: 420px;
6+
margin: 100px auto;
7+
padding: 20px 30px;
8+
border-radius: 6px;
9+
background-color: white;
10+
text-align: center;
11+
border: 1px solid $color--border;
12+
box-shadow: 1px 1px 3px rgba(0,0,0,.1);
13+
}

0 commit comments

Comments
 (0)