There are a few post on this subject but the light has not turned on yet.
I'm trying to extend a rails gem/engine Plutus to use acts_as_tenant
Plutus provides a double entry accounting system for an application. One of the limitations is that the design allows for only one customer or one set of books. What I am trying to do is add multi-tenancy using acts_as_tenant with as little as possible modifications to the Plutus engine. The goal is not to significantly alter Plutus with a different fork, but to add a few optional methods or attributes to Plutus that are only used if you want multiple accounts.
I have it semi-working, but need help in finding where to put stuff and help in clear up what is not working. The condensed Plutus models are:
class Account < ActiveRecord::Base
has_many :credit_amounts, :extend => AmountsExtension
has_many :debit_amounts, :extend => AmountsExtension
has_many :credit_transactions, :through => :credit_amounts, :source => :transaction
has_many :debit_transactions, :through => :debit_amounts, :source => :transaction
end
class Amount < ActiveRecord::Base
belongs_to :transaction
belongs_to :account
end
class Transaction < ActiveRecord::Base
belongs_to :commercial_document, :polymorphic => true
has_many :credit_amounts, :extend => AmountsExtension
has_many :debit_amounts, :extend => AmountsExtension
has_many :credit_accounts, :through => :credit_amounts, :source => :account
has_many :debit_accounts, :through => :debit_amounts, :source => :account
end
Then sti classes on Account: Asset, Equity, Expense, Liability, Revenue and sti classes on Amount: DebitAmount, CreditAmount. This is a little beyond my rails knowledge but this may be on of the most compact double entry schemes I've ever seen (I'm not an accountant, but I have had to add accounting features on apps in the past).
Semi-working means that the only thing I've modified in Plutus is adding a tenant_id
to the three models and getting acts_as_tenant to extend two of the three models. From the console on the main application I've found that:
Plutus::Account.acts_as_tenant(:tenant)
Plutus::Amount.acts_as_tenant(:tenant)
Plutus::Transaction.acts_as_tenant(:tenant)
works for Account and Transaction, but errors on Amount with uninitialized constant Transaction
, and I'm not sure why. Any ideas?
I've read the rails guide on engines and extending with decorators or concerns, but have not figured out how to send acts_as_tenant(:tenant)
to the model using those approaches. Where would I put those three lines of code in the main application (providing I figure out how to get Amount to work!)?
Is there a better approach?
I still have a few class methods that I will have to extend or modify, but no use trying that until I get over this first hurdle.
The problem was that Plutus is a name-spaced engine, and while it works fine within the engine, calling it from outside the engine (main app) could raise conflicts.
To fix it, a class_name option was added to the associations.
module Plutus
class Amount < ActiveRecord::Base
belongs_to :transaction, class_name:"Plutus::Transaction"
belongs_to :account, class_name:"Plutus::Account"
validates_presence_of :type, :amount, :transaction, :account
end
end
Still never figured out the best place to stick the ActsAsTenant
calls. I stuck them in the Concerns directory and they didn't get called. Ended up putting them in my Tenant model and all is fine.