Rails - Save tenant in Audited (formerly acts_as_audited)
Asked Answered
W

2

6

I have Audited (formerly acts_as_audited) setup and working. The user_id is successfully saved in the audit table but I can't figure out an efficient way to save the tenant_id (I have multitenancy setup with scopes). I have tried using the Associated Audits technique described in the README but that doesn't work for me.

My current solution is to use the after_audit callback in every model (can be implemented with Rails concerns) to get the last audit and save the tenant_id:

def after_audit
  audit = Audit.last
  audit.tenant_id = self.tenant_id
  audit.save!
end

Whilst this works it seems like it would be inefficient to have to query for the audit again and then update it. It would make more sense to me to add the tenant_id to the audit before it saves but I can't figure out how to do this. Is it possible to add the tenant_id to the audit before saving? If yes, then how?

EDIT:

I've also tried including my default tenant scope in my Audit model but it does not seem to be called:

audit.rb

class Audit < ActiveRecord::Base
 default_scope { where(tenant_id: Tenant.current_id) }

application_controller.rb

class ApplicationController < ActionController::Base
  around_action :scope_current_tenant

  def scope_current_tenant
    Tenant.current_id = current_tenant.id
    yield
  ensure
    Tenant.current_id = nil
  end

EDIT: 2/1/16

I still haven't implemented a solution to this however my current thoughts would be to use:

#model_name.rb
  def after_audit
    audit = self.audits.last
    audit.business_id = self.business_id
    audit.save!
  end

In this code we get the last audit for the current model. This way we are only dealing with the current model, there is no chance of adding the audit to another business (as far as I can tell). I would add this code into a concern to keep it DRY.

I still can't get normal Rails callbacks to work within the Audit model. The only other way I see at the moment is to fork and modified the gem source code.

Wiggly answered 26/11, 2014 at 9:42 Comment(2)
Marklar, did you find a solution for this problem?Capuche
@Capuche no, unfortunately I haven't. I've updated my question with how I would currently implement but I'm still not happy with the solution. Please post an answer to this question if you figure it out. Thanks.Wiggly
S
1

I have recently added Acts As Tenant gem to a Rails app that is running the Audited gem. I was running into the same problem. I had added

acts_as_tenant :account

to the Audit model but it didn't do anything. I learned that you can't override in the Audit model but have to create a custom audit model that inherits from it. So I created the model: custom_audit.rb

class CustomAudit < Audited::Audit
  acts_as_tenant :account
end

I then added the initializer file audited.rb in confi/initializers like so:

Audited.config do |config|
  config.audit_class = CustomAudit
end

I was still having the problem where all my multitenancy was working except the show_audit view. I finally deleted all of my audits from both tenants in my test setup. It worked! I can now add new audits and they scope just fine. But I still need to merge the actual client DBs into one, and I don't want to lose the history in the audit table... Not sure how to fix that.

So when I try to access the Audits it fails with current_tenant being nil. Not sure why deleting all of the current records in the table fixes it, but I need to find a way around it.

Secret answered 29/8, 2021 at 18:58 Comment(2)
I think my problem was I had not set an initializer for ActsAsTenant to set require_tenant = true. Working great now.Secret
how about using github.com/collectiveidea/audited#associated-audits ?Rheumatic
G
2

I was tasked with implementing Auditing, and also adding a reference to an Org. The migration adds this line:

t.references :org, type: :uuid, index: true, null: true

To save an org_id, I ended up writing an initializer - audited.rb. That file looks like this:

Rails.configuration.after_initialize do
  Audited.audit_class.class_eval do
    belongs_to :org, optional: true

    default_scope MyAppContext.context_scope

    before_create :ensure_org

    private

    def ensure_org
      return unless auditable.respond_to? :org_id

      self.org_id = auditable.org_id
    end
  end
end

Hope this helps!

Glisson answered 10/2, 2020 at 18:14 Comment(0)
S
1

I have recently added Acts As Tenant gem to a Rails app that is running the Audited gem. I was running into the same problem. I had added

acts_as_tenant :account

to the Audit model but it didn't do anything. I learned that you can't override in the Audit model but have to create a custom audit model that inherits from it. So I created the model: custom_audit.rb

class CustomAudit < Audited::Audit
  acts_as_tenant :account
end

I then added the initializer file audited.rb in confi/initializers like so:

Audited.config do |config|
  config.audit_class = CustomAudit
end

I was still having the problem where all my multitenancy was working except the show_audit view. I finally deleted all of my audits from both tenants in my test setup. It worked! I can now add new audits and they scope just fine. But I still need to merge the actual client DBs into one, and I don't want to lose the history in the audit table... Not sure how to fix that.

So when I try to access the Audits it fails with current_tenant being nil. Not sure why deleting all of the current records in the table fixes it, but I need to find a way around it.

Secret answered 29/8, 2021 at 18:58 Comment(2)
I think my problem was I had not set an initializer for ActsAsTenant to set require_tenant = true. Working great now.Secret
how about using github.com/collectiveidea/audited#associated-audits ?Rheumatic

© 2022 - 2024 — McMap. All rights reserved.