Ruby on Railsでマルチテナントアーキテクチャを実装し、Railsを学ぶためのサンドボックスです。
- docker-compose up -d
- ./bin/rails server
- http://localhost:3000 にアクセス
- gem install rails
初期プロジェクトコード生成 cf. #1
- rails new . --skip-bundle --skip-test --skip-turbolinks --skip-webpack-install --database=postgresql
- bundle install
DBセットアップ cf. #1
- postgresをコンテナで起動できるようにdocker-compose.ymlを作成
- username、password、hostをconfig/database.ymlに追加
- docker-compose up -d
- ./bin/rails db:createでDBを作成
Deviseの導入 cf. #2
cf.hearcombo/deviseを導入する。
- bundle add devise
- rails generate devise:install
- development.rbに以下を追加
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
- rails g devise User
- rails g devise:views
- rails g migration add_name_to_users name:string
- rails db:migrate
active-record-multi-tenantを導入。
tenantsテーブルを作成。
各テーブルにtenant_idを追加。
各modelに以下を追加。
multi_tenant :tenant
tenant事にデータを制御したいcontrollerに以下を追加。(application_controllerなどに共通処理として用意したほうが良さそう。)
set_current_tenant_through_filter # Required to opt into this behavior
before_action :set_tenant_as_tenant
def set_tenant_as_tenant
tenant = Tenant.find(current_user.tenant_id)
set_current_tenant(tenant)
end
これで、tenant_idを都度意識してデータを参照したり、書き込む必要がなくなる。
cf. ActiverecordMultiTenant でマルチテナンシー
debugbarの手順通り導入。
CMSっぽいものを実装。
CRUDのN+1を解消
gem 'bitemporal'
class User < ApplicationRecord
include Bitemporal
end
gem 'grape`
# inflections.rb
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.acronym 'API'
end
# config/routes.rb
mount API => '/'
# app/api/api.rb
class API < Grape::API
prefix 'api'
mount V1::Posts
end
# app/api/v1/posts.rb
module V1
class Posts < Grape::API
prefix 'api'
version 'v1', using: :path
format :json
get '/posts' do
Post.all
end
end
end
Redisを導入してキャッシュストアとして使う。
Rubocopを導入。
group :development do
gem 'rubocop', require: false
gem 'rubocop-performance', require: false
gem 'rubocop-rails', require: false
gem 'rubocop-rspec', require: false
end
bundle exec rubocop --auto-gen-config
bundle exec rubocop -A
// or
bundle exec rubocop --auto-correct
bundle exec rubocop
bundle exec rubocop --help
gem 'rspec-rails', '~> 6.1.0'
gem 'factory_bot_rails'
gem 'faker'
rails generate rspec:install
rails g rspec:model posts
# Gemfile
gem 'capybara'
gem 'launchy'
gem 'selenium-webdriver'
# Gemfile
require 'capybara/rspec`
RSpec.configure do |config|
config.include Devise::Test::ControllerHelpers, type: :controller
config.include Devise::Test::IntegrationHelpers, type: :system
config.include Warden::Test::Helpers
config.include Capybara::DSL
end
gem 'sidekiq'
rails g job sample
bundle exec sidekiq
gem 'spring'
bundle exec spring binstub --all