module MultiTenantSupport::ModelConcern
Public Instance Methods
belongs_to_tenant(name, **options)
click to toggle source
# File lib/multi_tenant_support/concern/model_concern.rb, line 7 def belongs_to_tenant(name, **options) options[:foreign_key] ||= MultiTenantSupport.model.default_foreign_key belongs_to name.to_sym, **options set_default_scope_under_current_tenant(options[:foreign_key]) set_tenant_account_readonly(name, options[:foreign_key]) MultiTenantSupport.model.tenanted_models << self.name end
set_default_scope_under_current_tenant(foreign_key)
click to toggle source
Calls superclass method
# File lib/multi_tenant_support/concern/model_concern.rb, line 19 def set_default_scope_under_current_tenant(foreign_key) default_scope lambda { if MultiTenantSupport.full_protected? scope_under_current_tenant else where(nil) end } scope :scope_under_current_tenant, lambda { raise MissingTenantError unless MultiTenantSupport.current_tenant tenant_account_primary_key = MultiTenantSupport.model.tenant_account_primary_key tenant_account_id = MultiTenantSupport.current_tenant.send(tenant_account_primary_key) where(foreign_key => tenant_account_id) } scope :unscope_tenant, -> { unscope(where: foreign_key) } override_unscoped = Module.new { define_method :unscoped do |&block| if MultiTenantSupport.full_protected? block ? relation.scope_under_current_tenant.scoping { block.call } : relation.scope_under_current_tenant else super(&block) end end } extend override_unscoped override_insert_all = Module.new { define_method :insert_all do |attributes, **arguments| raise MissingTenantError unless MultiTenantSupport.unprotected? || MultiTenantSupport.current_tenant super(attributes, **arguments) end define_method :insert_all! do |attributes, **arguments| raise MissingTenantError unless MultiTenantSupport.unprotected? || MultiTenantSupport.current_tenant super(attributes, **arguments) end } extend override_insert_all override_upsert_all = Module.new { define_method :upsert_all do |attributes, **arguments| warn "[WARNING] You are using upsert_all(or upsert) which may update records across tenants" unless MultiTenantSupport.unprotected? super(attributes, **arguments) end } extend override_upsert_all after_initialize do |object| next if object.new_record? && MultiTenantSupport.unprotected? next if object.persisted? && MultiTenantSupport.allow_read_across_tenant? raise MissingTenantError unless MultiTenantSupport.current_tenant raise InvalidTenantAccess if object.send(foreign_key) != MultiTenantSupport.current_tenant_id end before_save do |object| next if MultiTenantSupport.unprotected? raise MissingTenantError unless MultiTenantSupport.current_tenant raise NilTenantError if object.send(foreign_key).nil? raise InvalidTenantAccess if object.send(foreign_key) != MultiTenantSupport.current_tenant_id end override_update_columns_module = Module.new { define_method :update_columns do |attributes| unless MultiTenantSupport.unprotected? raise MissingTenantError unless MultiTenantSupport.current_tenant raise NilTenantError if send(foreign_key).nil? raise InvalidTenantAccess if send(foreign_key) != MultiTenantSupport.current_tenant_id end super(attributes) end } include override_update_columns_module override_delete = Module.new { define_method :delete do unless MultiTenantSupport.unprotected? raise MissingTenantError unless MultiTenantSupport.current_tenant raise InvalidTenantAccess if send(foreign_key) != MultiTenantSupport.current_tenant_id end super() end } include override_delete override_delete_by = Module.new { define_method :delete_by do |*args| unless MultiTenantSupport.unprotected? raise MissingTenantError unless MultiTenantSupport.current_tenant end super(*args) end } extend override_delete_by before_destroy do |object| unless MultiTenantSupport.unprotected? raise MissingTenantError unless MultiTenantSupport.current_tenant raise InvalidTenantAccess if object.send(foreign_key) != MultiTenantSupport.current_tenant_id end end end
set_tenant_account_readonly(tenant_name, foreign_key)
click to toggle source
Calls superclass method
# File lib/multi_tenant_support/concern/model_concern.rb, line 134 def set_tenant_account_readonly(tenant_name, foreign_key) readonly_tenant_module = Module.new { define_method "#{tenant_name}=" do |tenant| return super(tenant_account) if MultiTenantSupport.unprotected? raise NilTenantError if tenant.nil? raise MissingTenantError unless MultiTenantSupport.current_tenant if new_record? && tenant == MultiTenantSupport.current_tenant super tenant else raise ImmutableTenantError end end define_method "#{foreign_key}=" do |key| return super(tenant_account) if MultiTenantSupport.unprotected? raise NilTenantError if key.nil? raise MissingTenantError unless MultiTenantSupport.current_tenant if new_record? && key == MultiTenantSupport.current_tenant_id super key else raise ImmutableTenantError end end } include readonly_tenant_module attr_readonly foreign_key end