Module: Milia::Base::ClassMethods
- Defined in:
- lib/milia/base.rb
Overview
############################################################################# #############################################################################
Instance Method Summary collapse
-
#acts_as_tenant ⇒ Object
———————————————————————— acts_as_tenant – makes a tenanted model Forces all references to be limited to current_tenant rows ————————————————————————.
-
#acts_as_universal ⇒ Object
———————————————————————— acts_as_universal – makes a univeral (non-tenanted) model Forces all reference to the universal tenant (nil) ————————————————————————.
-
#acts_as_universal_and_determines_account ⇒ Object
———————————————————————— acts_as_universal_and_determines_tenant_reference All the characteristics of acts_as_universal AND also does the magic of binding a user to a tenant ————————————————————————.
-
#acts_as_universal_and_determines_tenant ⇒ Object
———————————————————————— ————————————————————————.
-
#current_tenant ⇒ Object
———————————————————————— current_tenant – returns tenant obj for current tenant return nil if no current tenant defined ————————————————————————.
-
#current_tenant_id ⇒ Object
———————————————————————— current_tenant_id – returns tenant_id for current tenant ————————————————————————.
-
#set_current_tenant(tenant) ⇒ Object
———————————————————————— set_current_tenant – model-level ability to set the current tenant NOTE: *USE WITH CAUTION* normally this should NEVER be done from the models …
-
#where_restrict_tenant(*args) ⇒ Object
———————————————————————— where_restrict_tenant – gens tenant restrictive where clause for each klass NOTE: subordinate join tables will not get the default scope by Rails theoretically, the default scope on the master table alone should be sufficient in restricting answers to the current_tenant alone ..
Instance Method Details
#acts_as_tenant ⇒ Object
acts_as_tenant – makes a tenanted model Forces all references to be limited to current_tenant rows
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/milia/base.rb', line 16 def acts_as_tenant() belongs_to :tenant validates_presence_of :tenant_id default_scope lambda { where("#{table_name}.tenant_id = ?", Thread.current[:tenant_id]) } # ..........................callback enforcers............................ after_initialize do |obj| # Whenever we initialize a new object it needs to have the correct tenant_id of the current_user. # Ensures that destroy can be called on tenanted records which haven't been persisted yet. obj.tenant_id ||= Thread.current[:tenant_id] end # ..........................callback enforcers............................ before_save do |obj| # force tenant_id to be correct for current_user # raise exception if updates attempted on wrong data raise ::Milia::Control::InvalidTenantAccess unless obj.tenant_id == Thread.current[:tenant_id] end # ..........................callback enforcers............................ before_destroy do |obj| # force tenant_id to be correct for current_user if (obj.tenant_id != Thread.current[:tenant_id]) raise ::Milia::Control::InvalidTenantAccess end end end |
#acts_as_universal ⇒ Object
acts_as_universal – makes a univeral (non-tenanted) model Forces all reference to the universal tenant (nil)
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/milia/base.rb', line 48 def acts_as_universal() belongs_to :tenant default_scope { where("#{table_name}.tenant_id IS NULL") } # ..........................callback enforcers............................ before_save do |obj| # force tenant_id to be universal if obj.tenant_id.present? raise ::Milia::Control::InvalidTenantAccess end end # ..........................callback enforcers............................ before_destroy do |obj| # force tenant_id to be universal raise ::Milia::Control::InvalidTenantAccess unless obj.tenant_id.nil? end end |
#acts_as_universal_and_determines_account ⇒ Object
acts_as_universal_and_determines_tenant_reference All the characteristics of acts_as_universal AND also does the magic of binding a user to a tenant
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/milia/base.rb', line 72 def acts_as_universal_and_determines_account() include ::Milia::InviteMember has_and_belongs_to_many :tenants acts_as_universal() # validate that a tenant exists prior to a user creation before_create do |new_user| if Thread.current[:tenant_id].blank? || !Thread.current[:tenant_id].kind_of?(Integer) || Thread.current[:tenant_id].zero? raise ::Milia::Control::InvalidTenantAccess, "no existing valid current tenant" end end # before create callback do # before create, tie user with current tenant after_create do |new_user| tenant = Tenant.find(Thread.current[:tenant_id]) unless tenant.users.include?(new_user) new_user.skip_reconfirmation! # For details why this is needed see milia issue #68 tenant.users << new_user # add user to this tenant if not already there end end # before_create do before_destroy do |old_user| old_user.tenants.clear # remove all tenants for this user end # before_destroy do end |
#acts_as_universal_and_determines_tenant ⇒ Object
106 107 108 109 110 111 112 113 114 115 |
# File 'lib/milia/base.rb', line 106 def acts_as_universal_and_determines_tenant() has_and_belongs_to_many :users acts_as_universal() before_destroy do |old_tenant| old_tenant.users.clear # remove all users from this tenant true end # before_destroy do end |
#current_tenant ⇒ Object
current_tenant – returns tenant obj for current tenant return nil if no current tenant defined
121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/milia/base.rb', line 121 def current_tenant() begin tenant = ( Thread.current[:tenant_id].blank? ? nil : Tenant.find(Thread.current[:tenant_id]) ) return tenant rescue ActiveRecord::RecordNotFound return nil end end |
#current_tenant_id ⇒ Object
current_tenant_id – returns tenant_id for current tenant
139 140 141 |
# File 'lib/milia/base.rb', line 139 def current_tenant_id() return Thread.current[:tenant_id] end |
#set_current_tenant(tenant) ⇒ Object
set_current_tenant – model-level ability to set the current tenant NOTE: *USE WITH CAUTION* normally this should NEVER be done from the models … it’s only useful and safe WHEN performed at the start of a background job (DelayedJob#perform)
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/milia/base.rb', line 149 def set_current_tenant(tenant) # able to handle tenant obj or tenant_id case tenant when Tenant then tenant_id = tenant.id when Integer then tenant_id = tenant else raise ArgumentError, "invalid tenant object or id" end # case old_id = (Thread.current[:tenant_id].nil? ? '%' : Thread.current[:tenant_id]) Thread.current[:tenant_id] = tenant_id logger.debug("MILIA >>>>> [Tenant#change_tenant] new: #{tenant_id}\told:#{old_id}") unless logger.nil? end |
#where_restrict_tenant(*args) ⇒ Object
where_restrict_tenant – gens tenant restrictive where clause for each klass NOTE: subordinate join tables will not get the default scope by Rails theoretically, the default scope on the master table alone should be sufficient in restricting answers to the current_tenant alone .. HOWEVER, it doesn’t feel right. adding an additional .where( where_restrict_tenants(klass1, klass2,…)) for each of the subordinate models in the join seems like a nice safety issue.
177 178 179 |
# File 'lib/milia/base.rb', line 177 def where_restrict_tenant(*args) args.map { |klass| "#{klass.table_name}.tenant_id = #{Thread.current[:tenant_id]}" }.join(" AND ") end |