Rahul
Rahul

Reputation: 47096

Implementing multi tenancy in rails

We have a medium size application deployed for multiple clients on respective online VPS servers. The code is same for all the clients. Maintenance is becoming a huge burden. Even a same change, we have deploy in so many servers. So we are planning to implement multi tenancy feature for our application.

We came across a few gems but that doesn't server the purpose and hence we are planning to implement it.

We have created a new model Client and We have created an abstract superclass which inherits from ActiveRecord::Base and all the dependent classes inherit this class. Now the problem comes when I wanna add default_scope from my superclass.

class SuperClass < ActiveRecord::Base
  self.abstract_class = true
  default_scope where(:client_id => ???)
end 

The ??? changes for every user. So I cant give static value. But I am not sure how I can dynamically set this scope. So what can be done?

Upvotes: 4

Views: 904

Answers (1)

bioneuralnet
bioneuralnet

Reputation: 5301

We do something like the following (you may not need the thread-safe part):

class Client < ActiveRecord::Base
  def self.current
    Thread.current['current_client']
  end

  def self.current=(client)
    Thread.current['current_client'] = client
  end
end

class SuperClass < ActiveRecord::Base
  self.abstract_class = true
  # Note that the default scope has to be in a lambda or block. That means it's eval'd during each request.
  # Otherwise it would be eval'd at load time and wouldn't work as expected.
  default_scope { Client.current ? where(:client_id => Client.current.id ) : nil }
end

Then in ApplicationController, we add a before filter to set the current Client based on the subdomain:

class ApplicationController < ActionController::Base
  before_filter :set_current_client

  def set_current_client
    Client.current = Client.find_by_subdomain(request.subdomain)
  end
end

Upvotes: 5

Related Questions