{"id":13879256,"url":"https://github.com/zauberware/rails-devise-graphql","last_synced_at":"2025-04-07T08:27:36.714Z","repository":{"id":35836961,"uuid":"169886066","full_name":"zauberware/rails-devise-graphql","owner":"zauberware","description":"A Rails 6 boilerplate to create your next Saas product. Preloaded with graphQL, devise, JWT, CanCanCan, RailsAdmin, Rubocop, Rspec, i18n and more.","archived":false,"fork":false,"pushed_at":"2023-01-19T11:40:57.000Z","size":337,"stargazers_count":285,"open_issues_count":12,"forks_count":53,"subscribers_count":15,"default_branch":"master","last_synced_at":"2024-12-18T06:23:02.197Z","etag":null,"topics":["api-only","authentication-backend","boilerplate","boilerplate-template","devise","devise-jwt","graphql","graphql-api","graphql-server","hackathon-starter","i18n","rails-api","rails-api-starter","rails6","railsadmin","rspec-rails","ruby-on-rails","rubyonrails","saas","saas-boilerplate"],"latest_commit_sha":null,"homepage":"https://www.zauberware.com","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zauberware.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-02-09T16:20:55.000Z","updated_at":"2024-12-17T08:03:39.000Z","dependencies_parsed_at":"2023-02-10T23:31:06.307Z","dependency_job_id":null,"html_url":"https://github.com/zauberware/rails-devise-graphql","commit_stats":null,"previous_names":[],"tags_count":4,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zauberware%2Frails-devise-graphql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zauberware%2Frails-devise-graphql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zauberware%2Frails-devise-graphql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zauberware%2Frails-devise-graphql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zauberware","download_url":"https://codeload.github.com/zauberware/rails-devise-graphql/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247617984,"owners_count":20967700,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-only","authentication-backend","boilerplate","boilerplate-template","devise","devise-jwt","graphql","graphql-api","graphql-server","hackathon-starter","i18n","rails-api","rails-api-starter","rails6","railsadmin","rspec-rails","ruby-on-rails","rubyonrails","saas","saas-boilerplate"],"created_at":"2024-08-06T08:02:15.415Z","updated_at":"2025-04-07T08:27:36.689Z","avatar_url":"https://github.com/zauberware.png","language":"Ruby","readme":"# 💎 Rails 6 boilerplate with devise, JWT, graphQL, CanCanCan and RailsAdmin.\n[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/zauberware/rails-devise-graphql/graphs/commit-activity)\n[![GitHub license](https://img.shields.io/github/license/Naereen/StrapDown.js.svg)](https://github.com/zauberware/rails-devise-graphql/blob/master/LICENSE)\n![GitHub top language](https://img.shields.io/github/languages/top/zauberware/rails-devise-graphql)\n![GitHub issues](https://img.shields.io/github/issues/zauberware/rails-devise-graphql)\n\nThis is a boilerplate to build your next SaaS product. It's a RubyOnRails 6 backend with authentication, GraphQL API, Roles \u0026 Ability management and a admin dashboard. It works nicely together with clients made with **Angular, React, Vue.js, React.Native, Swift, Kotlin** or any other client framework which implements the [JSON Web Tokens](https://jwt.io/introduction/) philosophy.\n\n### Versions\n\n- Current ruby version `2.6.x`\n- Bundler version `2.1.4`\n- Rails version `6.0.X`\n- PostgreSQL Server as db connector\n\n### Dependencies\nThis boilerplate works like a charm with the following gems:\n- pg\n- devise\n- devise_invitable\n- graphql\n- graphql-auth\n- graphql-errors\n- rack-cors\n- rack_attack\n- rails_admin\n- cancancan\n- image_processing\n- mini_magick\n- puma\n- bootsnap\n- friendly_id\n- dotenv\n\n\n## 🚀 Quick start\n\nYou can have a running backend in seconds on [heroku](https://www.heroku.com):\n\n[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/zauberware/rails-devise-graphql) \n\nor clone this repo:\n\n```sh\ngit clone https://github.com/zauberware/rails-devise-graphql my-saas-backend\ncd my-saas-backend\n```\n\nClone `env_sample` to .env for local development. We set it up with default rails `3000` and client  `8000` ports:\n\n```sh\ncp env_sample .env\n```\n\nInstall the bundle:\n\n```sh\nbundle install\n```\n\nMake sure the PostgreSQL is running on localhost. You may have to change your credentials under `/config/database.yml`:\n\n```sh\nrake db:create\nrake db:migrate\nrake db:seed\n```\n\nRun the development server:\n\n```sh\nrails s\n```\n\nDownload a GraphQL client like [GraphiQL](https://github.com/graphql/graphiql) or others to access and test your API. Point the GraphQL IDE to `http://0.0.0.0:3000/graphql`\n\n**Note:** Make sure that the `.env` file is included in the root of your project and you have defined `CLIENT_URL` and `DEVISE_SECRET_KEY`. Read more about the JSON Web Token [this](https://github.com/zauberware/rails-devise-graphql). There are plenty of packages available.\n\n## 🎁 What's included?\n\n### 1. Database\nThe app uses a PostgreSQL database. It implements the connector with the gem `pg`. The app already includes a `User` and a `Company` model with basic setup. We see an `Company` as a company with it's users. We did **not** add multi-tenancy to this app. If you want to do it by yourself check out the [apartment](https://github.com/influitive/apartment) gem.\n\n\n### 2. Authentication\nThe 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.\n\nChange devise settings under `config/initializers/devise.rb` and `config/initializers/graphql_auth.rb`.\n\n#### Invitations\nAdmins of a company can invite new users. The process is handled with `devise_invitable`. We added a `inviteUser` and `acceptInvite` mutation to handle this process via graphql.\n\nLike in the reset password process we redirect the users to the frontend domain and not to backend.\n\n\n### 3. JSON Web Token\n[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.\n\n\n### 4. GraphQL\n[graphql-ruby](https://github.com/rmosolgo/graphql-ruby) is a Ruby implementation of GraphQL. Sadly it's not 100% open source, but with the free version allows you amazing things to do. See the [Getting Started Guide](https://graphql-ruby.org/) and the current implementations in this project under `app/graphql/`.\n\n#### Filters, Sorting \u0026 Pagination\nOur `BaseResolver` class provides everything you need to achieve filter, sorting and pagination. Have a look at the resolver `resolvers/users/users.rb`:\n\n**How to:**\n\nInclude `SearchObject` module in your resolver:\n\n```ruby\n  class Users \u003c Resolvers::BaseResolver\n      include ::SearchObject.module(:graphql)\n```\n\nDefine the scope for this resolver:\n\n```ruby\nscope { resources }\n\ndef resources\n  ::User.accessible_by(current_ability)\nend\n```\n\nSet a connection_type as return type to allow pagination:\n```ruby\ntype Types::Users::UserType.connection_type, null: false\n```\n\nSet `order_by` as query option and define allowed order attributes:\n\n```ruby\noption :order_by, type: Types::ItemOrderType, with: :apply_order_by\ndef allowed_order_attributes\n  %w[email first_name last_name created_at updated_at]\nend\n```\n\nAllow filtering with a custom defined filter object \u0026 define allowed filter attributes:\n\n```ruby\n# inline input type definition for the advanced filter\nclass UserFilterType \u003c ::Types::BaseInputObject\n  argument :OR, [self], required: false\n  argument :email, String, required: false\n  argument :first_name, String, required: false\n  argument :last_name, String, required: false\nend\noption :filter, type: UserFilterType, with: :apply_filter\ndef allowed_filter_attributes\n  %w[email first_name last_name]\nend\n```\n\n#### Schema on production\n\nWe have disabled introspection of graphQL entry points here `app/graphql/graphql_schema.rb`. Remove `disable_introspection_entry_points` if you want to make the schema public accessible.\n\n\n### 5. CORS\nProtect your app and only allow specific domains to access your API. Set `CLIENT_URL=` in `.env` to your prefered client. If you need advanced options please change the CORS settings here `config/initializers/cors.rb`.\n\n\n### 6. App server\nThe 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.\n\n\n### 7. UUID\nThe 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).\n\n\n### 8. Automatic model annotation\nAnnotates Rails/ActiveRecord Models, routes, fixtures, and others based on the database schema. See [annotate_models gem](https://github.com/ctran/annotate_models).\n\nRun `$ annotate` in project root folder to update annotations.\n\n\n### 9. Abilities with CanCanCan\n[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.\n\nStart defining your abilities under `app/models/ability.rb`\u001c.\n\n\n### 10. Rails Admin\nTo access the data of your application you can access the [rails_admin](https://github.com/sferik/rails_admin) dashboard under route `http://0.0.0.0:3000/admin`. Access is currently only allowed for users with super admin role.\n\nIf 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`.\n\nChange rails_admin settings under `config/initializers/rails_admin.rb`.\n\n\n### 11. I18n\nThis app has the default language `en` and already set a secondary language `de`. We included the [rails-i18n](https://github.com/svenfuchs/rails-i18n) to support other languages out of the box. Add more languages under `config/initializers/locale.rb`.\n\n#### Setting locale\n\nTo switch locale just append `?locale=de` at the end of your url. If no `locale` param was set it uses browser default language (request env `HTTP_ACCEPT_LANGUAGE`). If this is unknown it takes the default language of the rails app.\n\n#### Devise\n\nFor devise we use [devise-i18n](https://github.com/tigrish/devise-i18n) to support other languages.\n\nChange translations under `config/locales/devise`.\u001cIf you want to support more languages install them with `rails g devise:i18n:locale fr`. (\u003c-- installs French)\n\n#### Rails Admin\n\nTo get translations for rails admin out of the box we use [rails_admin-i18n](https://github.com/starchow/rails_admin-i18n).\n\n#### Testing Locales\n\nHow to test your locale files and how to find missing one read [this](https://github.com/svenfuchs/rails-i18n#testing-your-locale-file).\n\n\n### 12. HTTP Authentication\nFor your staging environment we recommend to use a HTTP Auth protection. To enable it set env var `IS_HTTP_AUTH_PROTECTED` to `true`.\n\nSet user with `HTTP_AUTH_USER` and password with `HTTP_AUTH_PASSWORD`.\n\nWe enable HTTP auth currently for all controllers. The `ApplicationController` class includes the concern `HttpAuth`. Feel free to change it.\n\n\n### 13. Auto generated slugs\nTo provider more user friendly urls for your frontend we are using [friendly_id](https://github.com/norman/friendly_id) to auto generate slugs for models. We have already implemented it for the `Company` model. For more configuration see `config/initializers/friendly_id.rb`.\n\nTo create a new slug field for a model add a field `slug`:\n\n```sh\n$ rails g migration add_slug_to_resource slug:uniq\n$ bundle exec rake db:migrate\n```\n\nEdit your model file as the following:\n\n```ruby\nclass Company \u003c ApplicationRecord\n  extend FriendlyId\n  friendly_id :name, use: :slugged\nend\n```\n\nReplace traditional `Company.find(params[:id])` with `Company.friendly.find(params[:id])`\u001c\u001c\n```ruby\n  company = Company.friendly.find(params[:id])\n```\n\n\n### 14. Testing\n\nWe are using the wonderful framework [rspec](https://github.com/rspec/rspec). The test suit also uses [factory_bot_rails](https://github.com/thoughtbot/factory_bot_rails) for fixtures.\n\nRun `rspec spec`\n\n#### FactoryBot\n\nTo 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), including factory inheritance.\n\n#### Faker\n\nCreate fake data easily with [faker gem](https://github.com/faker-ruby/faker). Caution: The created data is not uniq by default.\n\n#### Shoulda Matchers\n\n[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.\n\n#### Simplecov\n\n[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.\n\nOpen test coverage results with \n\n```sh\n  $ open /coverage/index.html\n```\n\n### 15. Linter with Rubocop\n\nWe are using the wonderful [rubocop](https://github.com/rubocop-hq/rubocop-rails) to lint and auto fix the code. Install the rubocop VSCode extension to get best experience during development.\n\n### 16. Security with Rack Attack\nSee `config/initializers/rack_attack.rb` file. We have defined a common set of rules to block users trying to access the application multiple times with wrong credentials, or trying to create a hundreds requests per minute.\n\nTo speed up tests add this to your `.env.test`\n\n```\nATTACK_REQUEST_LIMIT=30\nATTACK_AUTHENTICATED_REQUEST_LIMIT=30\n```\n\n### 17. Sending emails\nSet your SMTP settings with these environment variables:\n- `SMTP_ADDRESS`\n- `SMTP_PORT`\n- `SMTP_DOMAIN`\n- `SMTP_USERNAME`\n- `SMTP_PASSWORD`\n- `SMTP_AUTH`\n- `SMTP_ENABLE_STARTTLS_AUTO`\n\nHave a look at `config/environments/production.rb` where we set the `config.action_mailer.smtp_settings`.\n\n#### from: email\n\nSet the email address for your `ApplicationMailer` and devise emails with env var `DEVISE_MAILER_FROM`.\n\n\n### 18. Deployment\nThe project runs on every server with ruby installed. The only dependency is a PostgreSQL database. Create a block `production:` in the`config/database.yml` for your connection.\n\n#### Heroku\n\n[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/zauberware/rails-devise-graphql)\n\nChoose the one click installer or push a clone of this repo to heroku by yourself. We added a `Profile` to the project and heroku run the `release:` statement after deploying a new version. Heroku will automatically set the db settings for your project, so there is nothing to do in `config/database.yml`.\n\n**Make sure all ENV vars are set and the database settings are valid.**\n\n#### Bitbucket Pipelines\n\nIf you want to use [Bitbucket pipelines](https://bitbucket.org/product/de/features/pipelines) for CI you can use the sample file `bitbucket-pipelines.yml` in the project root.\n\nMake sure to set ENV vars `$HEROKU_API_KEY` and `$HEROKU_APP_NAME` in Bitbuckets pipeline settings. (Will appear after enabling pipelines for your project.)\n\nThe pipeline has 2 environments: staging and production. Staging pipeline is getting triggered in `develop` branch. Production deploy triggered by `master` branch.\n\nIt also triggers pipeline while opening a PR.\n\n## What's missing?\n- Check \u0026 retest locked accounts\n- Invite for users, inviteMutation \u0026 acceptInviteMutation\n- Registration add more fields (Firstname, Last name)\n- Tests for filter, sorting \u0026 pagination\n- Security: brakeman and bundler-audit\n\nFeel free to make feature request or join development!\n\n## Share this repo\nHelp us to get more attention to this project:\n\n![Twitter URL](https://img.shields.io/twitter/url?label=Tweet%20about%20this%20project\u0026style=social\u0026url=https%3A%2F%2Fgithub.com%2Fzauberware%2Frails-devise-graphql)\n\n## 🚀 Contributors, backers \u0026 sponsors\n\nThis project exists thanks to all the **people who contribute**.\n\u003ca href=\"https://github.com/zauberware/rails-devise-graphql/graphs/contributors\"\u003e\u003cimg src=\"https://opencollective.com/rails-devise-graphql/contributors.svg?width=890\u0026button=false\" /\u003e\u003c/a\u003e\n\nThank you to **all our backers**! 🙏 ([Become a backer](https://opencollective.com/rails-devise-graphql#backer))\n\n\u003ca href=\"https://opencollective.com/rails-devise-graphql#backers\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/rails-devise-graphql/backers.svg?width=890\"\u003e\u003c/a\u003e\n\n**Support this project by becoming a sponsor.** Your logo will show up here with a link to your website. ([Become a sponsor](https://opencollective.com/rails-devise-graphql#sponsor))\n\n\u003ca href=\"https://opencollective.com/rails-devise-graphql/sponsor/0/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/rails-devise-graphql/sponsor/0/avatar.svg\"\u003e\u003c/a\u003e\n\n\n## ❤️ Code of Conduct\n\nPlease note that zauberware has a [Code of Conduct](https://github.com/zauberware/rails-devise-graphql/blob/master/CODE_OF_CONDUCT.md). By participating in this project online or at events you agree to abide by its terms.\n\n\n## Author\n\n__Script:__ \u003chttps://github.com/zauberware/rails-devise-graphql\u003e\n\n__Author website:__ [https://www.zauberware.com](https://www.zauberware.com)\n\n![zauberware technologies](https://avatars3.githubusercontent.com/u/1753330?s=200\u0026v=4)\n\n","funding_links":["https://opencollective.com/rails-devise-graphql"],"categories":["Ruby","Starters/Boilerplates","Implementations","Examples","Uncategorized"],"sub_categories":["Ruby","Ruby Examples","Uncategorized","Articles"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzauberware%2Frails-devise-graphql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzauberware%2Frails-devise-graphql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzauberware%2Frails-devise-graphql/lists"}