Allow rendering different views per tenant

Sometimes it might be convenient to use completely different views for
different tenants. For example, a certain tenant might use a footer that
has nothing to do with the default one.

For these cases, instead of adding `case Tenant.current_schema`
conditions to the view, it might be tidier to use a different file.

For this purpose, we're using Rails variants [1], which means that a
tenant named `mytenant` will use a template ending with
`.html+mytenant.erb` if it's available.

This works with components too, but has a limitation: when using the
`custom/` folder to add ERB files for a tenant, the default tenant ERB
file needs to be added to the `custom/` folder as well; if there aren't
changes to this file, a symbolic link will do.

For example, if we're writing a custom `admin/action_component` view for
the tenant `milky-way` but don't need to change this file for the
default tenant:

1. Create `app/components/custom/admin/action_component.rb` according to
   the components customizations documentation [2]
2. Create the custom view for the `milky-way` tenant and save it under
   `app/components/custom/admin/action_component.html+milky-way.erb`
3. Enter the `app/components/custom/admin/` folder and run `ln -s
   ../../admin/action_component.html.erb`

We're also adding some controller tests. Since Rails doesn't load the
middleware during controller tests, we're stubbing the `current_schema`
method directly instead of changing the subdomain of the request.

[1] https://guides.rubyonrails.org/v6.0/layouts_and_rendering.html#the-variants-option
[2] https://docs.consulproject.org/docs/english-documentation/customization/components
This commit is contained in:
Javi Martín
2022-11-03 00:10:28 +01:00
parent 0971de1ffd
commit 18611f32f1
5 changed files with 39 additions and 0 deletions

View File

@@ -1,6 +1,7 @@
require "application_responder"
class ApplicationController < ActionController::Base
include TenantVariants
include GlobalizeFallbacks
include HasFilters
include HasOrders

View File

@@ -0,0 +1,13 @@
module TenantVariants
extend ActiveSupport::Concern
included do
before_action :set_tenant_variant
end
private
def set_tenant_variant
request.variant = Tenant.current_schema.to_sym
end
end

View File

@@ -1,4 +1,5 @@
class Management::BaseController < ActionController::Base
include TenantVariants
include GlobalizeFallbacks
layout "management"
default_form_builder ConsulFormBuilder

View File

@@ -1,6 +1,7 @@
require "manager_authenticator"
class Management::SessionsController < ActionController::Base
include TenantVariants
include GlobalizeFallbacks
include AccessDeniedHandler
default_form_builder ConsulFormBuilder

View File

@@ -0,0 +1,23 @@
require "rails_helper"
describe TenantVariants do
controller(ActionController::Base) do
include TenantVariants
def index
render plain: request.variant
end
end
it "uses the default tenant by default" do
get :index
expect(response.body).to eq "[:public]"
end
it "uses the current tenant schema when defined" do
allow(Tenant).to receive(:current_schema).and_return("random-name")
get :index
expect(response.body).to eq '[:"random-name"]'
end
end