Multitenancy no Ruby On Rails: Implemente rapidamente

Multitenancy no Ruby On Rails

 

E ai programador(a), já conhece o conceito de Multitenancy?

Para entendermos esse conceito, vamos falar um pouco do modelo de uso de softwares pelas empresas. O mais comum até pouco tempo atrás (nos últimos anos) era as empresas comprarem uma cópia de um software (ou licença), instalarem em uma máquina local e utilizarem (mas isso veio progressivamente mudando).

Com a popularização do SaaS (Software as Service), os softwares em geral passaram a ficar na nuvem e as empresas passaram a pagar para utiliza-lo (ou seja, aluga-lo) se tornando inquilinos (ou em inglês tenants) da empresa que oferece o serviço.

 

As empresas que alugam esses softwares em geral necessitam que seus ambientes sejam separados e que a falha no software que um outro inquilino teve não afete o seu uso do produto. A arquitetura multitenancy (em tradução livre: múltiplos inquilinos) vem para nos ajudar a resolver essas necessidades e entregar software de qualidade.

 

Nesta arquitetura cada “tenant” (empresa que contratou o SaaS por exemplo) pode ter seus dados e configurações isolados dos outros inquilinos (apenas os membros daquele tenant vão poder ver e modificar os dados relacionados a ele), embora a aplicação que estará rodando seja apenas uma para todos os tenants.

Nesse Artigo você vai aprender a implementar o Multitenancy em um APP Ruby On Rails rapidamente, bora? 😁

 

Gem Apartment

Em aplicações Ruby on Rails, é possível utilizar uma gem chamada Apartment para facilitar a implementação dessa arquitetura. Ela é capaz de isolar dados baseados em uma conta ou empresa e permitir que outras informações estejam em um inquilino em comum.

 

O que vamos criar

Para que o conceito fique claro, vamos criar um projeto exemplo que exibirá informações sobre empresas. Os usuários autenticados poderão cadastrar sua empresa e adicionar uma lista de funcionários.

A gem Apartment nos ajudará a isolar os dados(funcionários) de cada empresa.

 

Ferramentas

  • • Ruby 2.5
  • • Rails 5.2
  • • Twitter Bootstrap Rails
  • • Jquery Rails
  • • Devise
  • • Devise Bootstrapped
  • • Apartment

 

Caso não tenha o ruby, postgres ou rails instalados, prepare seu ambiente de desenvolvimento com este breve tutorial: Instalando o Rails e suas dependências no Linux

 


Criando nossa Aplicação de exemplo

 

Preparando o Projeto

Nesta primeira etapa você irá criar o projeto e adicionar as gems necessárias.

 

1- Crie o projeto rodando:

2- Adicione as seguintes gems ao Gemfile

3- Instale as gems adicionadas executando

4- Para incluir os arquivos javascript das gems “Twitter Bootstrap Rails” e jQuery substitua o código de app/assets/javascripts/application.js por:

5- Rode o seguinte generate para incluir o bootstrap aos assets do projeto

 

Instalando o Devise

Agora você irá configurar a autenticação da aplicação com a gem Devise.

 

1- Rode o generator a seguir para criar o arquivo de configuração inicial do devise e o arquivo com os textos utilizados pelo i18n

2- Crie o model e as views do devise

3- Crie o banco de dados e execute a migration criada no passo anterior

4- Para exigir que o usuário se autentique antes de acessar alguma rota da aplicação, substitua o código de app/controllers/applications_controller.rb por:

 

Criando a Company

Nessa etapa você disponibilizará as funcionalidades de criar uma nova empresa e listar todas as empresas.

 

1- Crie o model Company, ele possuirá os atributos nome, descrição e subdomínio.

O atributo subdomínio existe porque o usuário irá incluí-lo ao endereço para acessar a página de uma empresa.

2- Execute a migration criada

3- Crie o controller Companies com as actions index e new

4- Substitua o conteúdo de app/controllers/companies_controller.rb por:

Aqui estamos criando um controller simples (parecido com um CRUD) que vai permitir a criação de uma nova company e a listagem de todas as companies.

5- Adicione as rotas do controller Companies substituindo o código do arquivo config/routes.rb por:

companies#index será a rota raiz da aplicação.

6- Substitua o conteúdo de app/views/companies/new.html.erb por:

Você adicionou ao arquivo um formulário para a criação de uma nova company

7- Para listar todas as companies do projeto, substitua o código de app/views/companies/index.html.erb por:

 

Preparando a gem Apartment

Agora você irá instalar e configurar a gem Apartment

 

1- Adicione ao seu Gemfile

2- Instale a gem executando

3- Crie o arquivo de configuração da gem apartment rodando

4. Realize configurações da gem apartment substituindo o código de config/inititializers/apartment.rb por:

Em excluded_models você informou quais models não são base de dados isoladas. Eles fazem parte de um ambiente compartilhado, guardando dados de todos usuários do sistema.

Em tenant_names você informou quais são os Inquilinos da aplicação. O apartment usa eles para rodar migrations para todos os inquilinos.

Também está configurado para que o middleware utilize configurações de subdomínio do Apartment. Desta forma, através da requisição a gem define qual inquilino será utilizado. Existe outras formas de fazer isso, para mais detalhes consulte a documentação da gem.

5-  Continuando, adicione um callback ao model Company para que um Tenant seja criado toda vez que uma empresa for cadastrada. O nome do Tenant será o conteúdo do atributo subdomínio.

Substitua o código de app/models/company.rb por:

Suba a aplicação (rails server) e cadastre uma nova empresa

Ao salvar a empresa o callback criou um Tenant com o nome do subdomínio.

 

 

Isolando Dados

Agora você irá criar um modelo para salvar dados de forma isolada.

 

1-  Crie o model de funcionários executando

2- Rode a migração criada

multitenancy

Perceba que a migração ocorreu no inquilino criado anteriormente. Se houvessem 10 inquilinos, a migração seria executada para todos.

3- Execute o generate para criar o controller Employees

4- Adicione ao controller app/controllers/employees_controller.rb as actions create e employee_params

5- Substitua o código de config/routes.rb por:

A constraint Subdomain verifica se o subdomínio existe e está da forma esperada. Somente quando o resultado é verdadeiro as rotas para companies#show e employees#create tornam-se disponíveis.

6- Adicione a action show ao controller Companies (app/controllers/companies_controller.rb).

Como o model Employee faz parte da base de dados isolada de um Tenant, quando a consulta Employees.all é realizada, será retornado apenas employees do Tenant em questão.

7- Crie um arquivo chamado show.html.erb com o comando

8- Adicione a ele o seguinte código:

Aqui é exibido o nome e descrição da empresa, um formulário para adicionar um novo funcionário e uma lista contendo todos funcionários da empresa.

9- Para compartilhar a sessão de um usuário entre subdomínios no devise, crie um arquivo de configuração rodando

10- Agora, adicione a ele o código:

 

Testando a implementação do Multitenancy

Vamos ver na prática como ficou o nosso projeto.

 

1- Para acessar subdomínios localmente utilize o endereço lvh.me ao em vez de localhost

2- Depois de realizar o login, crie uma nova empresa

3- Para acessar o Tenant da empresa, adicione o subdomínio a barra de endereço.

https://onebitcode.com/dating-advice-over-40/

4- Adicione alguns funcionários a esta empresa

chat dating site in usa for free without credit card required

5- Crie outra empresa, e acesse sua página de informações

https://onebitcode.com/tall-guys-dating-short-girl/

6- Mesmo fazendo uma consulta com Employee.all no controller show, não houve retorno de nenhum funcionário da primeira empresa.

Foi comprovado que os dados realmente estão isolados!!! 😁

 

Conclusão

Neste artigo você aprendeu em poucos minutos o que é e como utilizar a gem Apartment para criar aplicações SaaS com a arquitetura Multitenancy. A gem torna o processo muito simples para que você possa direcionar sua atenção às regras de negócio do projeto em questão.

Você conhecia o conceito de Multitenancy? Curtiu o artigo?
Deixe seu feedback pra gente 😀

 

 





12 formas de vencer o bloqueio criativo e escrever textos memoráveis (e 6 dicas extras)

Não perca nenhum conteúdo

Receba nosso resumo semanal com os novos posts, cursos, talks e vagas o/




Primeira vez no OneBitCode? Curtiu esse conteúdo?
O OneBitCode tem muito mais para você!


O OneBitCode traz conteúdos de qualidade, e em português, sobre programação com foco em Ruby on Rails e também JavaScript.
Além disso, aqui sempre levamos à você conteúdos valiosos sobre a carreira de programação, dicas sobre currículos, portfólios, perfil profissional, soft skills, enfim, tudo o que você precisa saber para continuar evoluindo como Programador(a)!

Fique por dentro de todos os conteúdos o/

 

Nossas redes sociais:

📹 • https://youtube.com/Onebitcode [Live todas as terças-feiras às 19h)
💻 • https://linkedin.com/company/onebitcode
🙂 • https://facebook.com/onebitcode
 📱  • https://instagram.com/one_bit_code
🐦 • https://twitter.com/onebitcode

 

Nossos cursos:

🥇 • Programador Full Stack Javascript em 8 Semanas
💎 • Curso Completo de Ruby
 ⚙  • Minicurso: API Rails 5 Completo
🐞 • Minicurso de Testes para Ruby on Rails com RSpec

 

Espero que curta nossos conteúdos e sempre que precisar de ajuda, fala com a gente!
E
stamos aqui para você 🙂

Bem-vindo à família OneBitCode o/

4 1 vote
Article Rating
janeiro 17, 2020
Subscribe
Notify of
guest
6 Comentários
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Tiago
4 anos atrás

muito bom.
Se alguém procura uma alternativa usando o apartment sem subdomain, eu escrevi uma alternativa usando session:
https://medium.com/@tiagoandrgeraldi/rails-app-with-multi-tenancy-without-subdomains-25941fe876ec
Aí nao precisa tratar o subdomain do host

Guilherme henrique
Guilherme henrique
4 anos atrás

Se eu utilizar um Vue ou um React no front o conceito segue o mesmo ?

Leonardo Scorza
Admin
4 anos atrás

Segue sim Guilherme 🙂

Lucas
Lucas
4 anos atrás

Olá, tive um problema depois de criar um tenant,
o rails db:migrate passou a acusar erro:

migrate tenant_name tenant
rake aborted!
NoMethodError: undefined method `migrate’ for ActiveRecord::Migrator:Class

Tasks: TOP => apartment:migrate
(See full trace by running task with –trace)

(isso ocorreu especificamente no passo 2 do tópico “isolando Dados”)

Guilherme
3 anos atrás

O employee seria o user do devise? Não entendi como isolaria o login.

Willyan
Willyan
2 anos atrás

Nesse exemplo qualquer usuário cadastrado consegue acessar os subdominos de todas as companies?

Feito com s2 por OneBitCode

6
0
Would love your thoughts, please comment.x
()
x
%d blogueiros gostam disto: