module Mongoid::Multitenancy::Document::ClassMethods
Constants
- MULTITENANCY_OPTIONS
List of authorized options
Attributes
Public Instance Methods
Redefine 'delete_all' to take in account the default scope
# File lib/mongoid/multitenancy/document.rb, line 98 def delete_all(conditions = nil) scope = scoped scope = scopewhere(conditions) if conditions scope.delete end
Redefine 'index' to include the tenant field in first position
# File lib/mongoid/multitenancy/document.rb, line 89 def index(spec, options = nil) if tenant_options[:full_indexes] spec = { tenant_field => 1 }.merge(spec) end super(spec, options) end
Defines the tenant field for the document.
@example Define a tenant.
tenant :client, optional: false, immutable: true, full_indexes: true
@param [ Symbol ] name The name of the relation. @param [ Hash ] options The relation options.
All the belongs_to options are allowed plus the following ones:
@option options [ Boolean ] :full_indexes If true the tenant field
will be added for each index.
@option options [ Boolean ] :immutable If true changing the tenant
wil raise an Exception.
@option options [ Boolean ] :optional If true allow the document
to be shared among all the tenants.
@option options [ Boolean ] :index If true build an index for
the tenant field itself.
@option options [ Boolean ] :scopes If true create scopes :shared
and :unshared.
@return [ Field ] The generated field
# File lib/mongoid/multitenancy/document.rb, line 32 def tenant(association = :account, options = {}) options = { full_indexes: true, immutable: true, scopes: true }.merge!(options) assoc_options, multitenant_options = build_options(options) # Setup the association between the class and the tenant class belongs_to association, assoc_options # Get the tenant model and its foreign key self.tenant_field = reflect_on_association(association).foreign_key.to_sym self.tenant_options = multitenant_options # Validates the tenant field validates_tenancy_of tenant_field, multitenant_options define_scopes if multitenant_options[:scopes] define_initializer association define_inherited association, options define_index if multitenant_options[:index] end
Validates whether or not a tenant field is correct.
@example Define the tenant validator
class Person include Mongoid::Document include Mongoid::Multitenancy::Document field :title tenant :client validates_tenant_of :client end
@param [ Array ] *args The arguments to pass to the validator.
# File lib/mongoid/multitenancy/document.rb, line 84 def validates_tenancy_of(*args) validates_with(TenancyValidator, _merge_attributes(args)) end
Validates whether or not a field is unique against the documents in the database.
@example
class Person include Mongoid::Document include Mongoid::Multitenancy::Document field :title validates_tenant_uniqueness_of :title end
@param [ Array ] *args The arguments to pass to the validator.
# File lib/mongoid/multitenancy/document.rb, line 66 def validates_tenant_uniqueness_of(*args) validates_with(TenantUniquenessValidator, _merge_attributes(args)) end
Private Instance Methods
@private
# File lib/mongoid/multitenancy/document.rb, line 107 def build_options(options) assoc_options = {} multitenant_options = {} options.each do |k, v| if MULTITENANCY_OPTIONS.include?(k) multitenant_options[k] = v assoc_options[k] = v if k == :optional else assoc_options[k] = v end end [assoc_options, multitenant_options] end
@private
Create the index
# File lib/mongoid/multitenancy/document.rb, line 170 def define_index index({ tenant_field => 1 }, background: true) end
@private
Define the inherited method
# File lib/mongoid/multitenancy/document.rb, line 138 def define_inherited(association, options) define_singleton_method(:inherited) do |child| child.tenant association, options.merge(scopes: false) super(child) end end
@private
Define the after_initialize
# File lib/mongoid/multitenancy/document.rb, line 126 def define_initializer(association) # Apply the default value when the default scope is complex (optional tenant) after_initialize lambda { if Multitenancy.current_tenant && new_record? send "#{association}=".to_sym, Multitenancy.current_tenant end } end
@private
Define the scopes
# File lib/mongoid/multitenancy/document.rb, line 148 def define_scopes # Set the default_scope to scope to current tenant default_scope lambda { if Multitenancy.current_tenant tenant_id = Multitenancy.current_tenant.id if tenant_options[:optional] where(tenant_field.in => [tenant_id, nil]) else where(tenant_field => tenant_id) end else all end } scope :shared, -> { where(tenant_field => nil) } scope :unshared, -> { where(tenant_field => Multitenancy.current_tenant.id) } end