This app is using Rails 7, Ruby 3, Vite and Vue 3 You could use this example app as a base for your new project, or as a tutorial that tells you which steps you need to start a project from scratch
This example app includes some gems that I'm using them for a long time. it wires up a number of things you might use in a real world Rails app, but at the same time it's not loaded up with a million personal opinions.
I used rails new baseapp -c tailwindcss -d postgresql
command to init the project to have based on importmaps and default configs, but I removed importmaps and tailwindcss and all default configs and moved to using Vite instead.
You can see the list of gems that I use in the project with the link of the related commit, so you can easily find what I configured for each gem.
Order by the commit I did:
- PostgreSQL (init project)
- RSpec (commit1) (commit2)
- Factory Bot Rails (commit)
- Faker (commit)
- Database Cleaner (commit)
- SimpleCov (commit)
- Rubocop(Check the Healthy app/Backend part)
- Annotate (commit)
- Pry (commit)
- Pagy (commit1) (commit2)
- HasScope (commit)
- JSON:API serializer A fast JSON:API serializer for Ruby Objects (commit)
- jsonapi.rb which provides some features for
jsonapi-serializer
PR and commit - jsonapi-rspec which provides some beautiful RSpec matchers for JSON API PR
- jsonapi.rb which provides some features for
- Action Cable (commit)
- Redis (commit)
- Sidekiq (commit)
- dotenv (commit)
- Vite Removing importmaps and all frontend libraries and Use Vite instead (PR)
- Code quality and format (Check Healthy app/Frontend part)
- Vue.js Vue.js version 3 (PR)
- RuboCop Code quality and format. First I added rubocop-rails_config gem by these two commits (commit1) (commit2), but after a while, I removed this gem and added rubocop gem and its extensions separately in this PR
- Brakeman Checking Ruby on Rails applications for security vulnerabilities. you can check
config/brakeman.ignore
to see ignore errors (PR) - bundler-audit Patch-level verification for bundler (PR)
- Fasterer Make Rubies code faster by suggestion some speed improvements. check
.fasterer.yml
to enable/disable suggestions (PR) - License Finder Check the licenses of the gems and packages. you can update
doc/dependency_decisions.yml
to manage licenses (PR)
- overcommit to manage and configure Git hooks by managing all healthy app tools. you can check
.overcommit.yml
to enable or disable tools. (PR) - Enabling github action to run
overcommit
after push and pull requests in github. Check.github/workflows/lint.yml
to see the github configs (PR)
- Devise and Devise::JWT JWT authentication solution Backend PR
We are using JWT to authentication using Devise and Devise::JWT gems. If you send a request to log in, the successful response will give you a header called Authorization
which has the JWT token as value. and you need to add this header and its value to all of your requests.
Predefined auth routes:
Request:
curl -XPOST -H "Content-Type: application/json" -d '{ "user": { "email": "test@example.com", "password": "12345678", "password_confirmation": "12345678" } }' http://localhost:3000/signup
Response: Returns the details of the created user
{"data":{"id":"4","type":"user","attributes":{"email":"test@example.com","sign_in_count":1,"created_at":"2022-04-18T17:49:06.798Z"}}}
Request:
curl -XPOST -i -H "Content-Type: application/json" -d '{ "user": { "email": "test@example.com", "password": "12345678" } }' http://localhost:3000/login
Response: includes Authorization
in header and details of the loggedin user
HTTP/1.1 200 OK
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 0
X-Content-Type-Options: nosniff
X-Download-Options: noopen
....
Content-Type: application/vnd.api+json; charset=utf-8
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0Iiwic2NwIjoidXNlciIsImF1ZCI6bnVsbCwiaWF0IjoxNjUwMzA0MjU3LCJleHAiOjE2NTAzOTA2NTcsImp0aSI6IjM4ZmI4ZGIyLWVlMjgtNDg2Yy05YjE5LTA2NWVmYmQ0ZGE4MCJ9.p8766vPrhiGpPyV2FdShw1ljBx2Os3D1oE_rPjjAYrY
...
{"data":{"id":"4","type":"user","attributes":{"email":"test@example.com","sign_in_count":2,"created_at":"2022-04-18T17:49:06.798Z"}}}
Request: includes Authorization
and its JWT token in the header of DELETE
request
curl -XDELETE -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0Iiwic2NwIjoidXNlciIsImF1ZCI6bnVsbCwiaWF0IjoxNjUwMzA0MjU3LCJleHAiOjE2NTAzOTA2NTcsImp0aSI6IjM4ZmI4ZGIyLWVlMjgtNDg2Yy05YjE5LTA2NWVmYmQ0ZGE4MCJ9.p8766vPrhiGpPyV2FdShw1ljBx2Os3D1oE_rPjjAYrY" -H "Content-Type: application/json" http://localhost:3000/logout
Response: nothing
Note We are using JWT to authentication, it means you can use this Rails base app as a vanilla rails app (Backend and frontend together), or as a Rails API app. both you can use.
I always prefer to have two apps for my projects, one for the part that will be shown public (I called it Website), and the second one for the part that you are managing there (I called it Panel), simplify you need to log in to have access there.
If you can check the codes you can see that there are two layout view files and two actions in application_controller, and two routes in routes.rb file. and for frontend there are two different entrypoints and routers ane etc.
In this case, you can use different technologies and UI Component Libraries in frontend, e.g. use Vuetify for Website and use VueTailwind for Panel. or even (it's a bit headache) but you can use React for Website and use Vue.js for Panel.
Two simple html/css templates have been added for Website and Panel. you can remove them easily
You need to do few small steps to run the app
git clone https://github.com/zakariaf/rails-base-app baseapp
cd baseapp
cp .env.example .env.local
Environment variables defined here(.env
), feel free to change or add variables as needed.
This file is ignored from git (Check .gitignore
) so it will never be commit.
If you use different values for environment variables in other envs, e.g. test, you need to copy one more: .env.test.local
Note .env.test
is used by github workflows.
create databases
rails db:setup
-
rails server
rails s
-
frontend app
yarn dev
This app is named baseapp
and the module is named BaseApp
. But for sure you would like to have a different name.
The only thing you need to do is just running the bin/rename-project yourappname YouAppName
script.
as you see this script needs 2 arguments:
- First argument: The lower case version of your app's name, such as
myapp
ormy_app
depending on your preference. - First argument: Used for your app's module name. such as
MyApp
bin/rename-project myapp MyApp
This script is going to:
- Perform a number of find / replace actions
- Initialize a new git repo for you (Optionally)
After that, If you're happy with your new project's name you can delete this script.
Or you can keep it around in case you decide to change your project's name later on.
I got the rename script idea and codes from Docker Rails Example project with some small changes.
- Add a JWT authentication solution
- Add cypress
- Dockerize
- automatic deploy process using capistrano
- add .gitlab-ci