Search code examples
ruby-on-railsrubymulti-tenant

ActiveRecord doesn't set ID of a shared model when creating a new instance


Wasn't entirely sure how to Google this exact question but the gist is that I have several models - User belongs to an Account, Assessment belongs to an Account, User and Assessment both have account_id in their tables. Any model that initializes another model in the same account should have the same account id. This is to ensure multitenant row-based data isolation in the application.

Here is roughly what my models look like. In fact, there are many other models that belongs_to Account and I'd like to make sure that all the data is tied to the correct Account.

class User < ApplicationRecord
  has_many :assessments

  default_scope { where(account_id: Account.current_id)}
end

class Assessment < ApplicationRecord
  belongs_to :user
end

class Account < ApplicationRecord
  has_many :users, dependent: :destroy
  has_many :assessments
  cattr_accessor :current_id

  validates_uniqueness_of :name, presence: true
end

Why doesn't this code work?

user = User.first
a = user.assessment.create
a.account_id == user.account_id # a.account_id is nil so this is False
acc = Account.first
user = acc.users.first
a = user.assessment.create
a.account_id == user.account_id # a.account_id is nil so this is False

Am I wrong to assume that Rails should manage this for me? Is there an alternative that will help ensure that if one model creates another model and both models have an account_id field, the new instance will be created with the same value?

The only alternative that I can see is manually setting the account id at every object creation.


Solution

  • There's no way for the create method to know anything about the user object. You have to pass the account: user.account into the method in order to create that "back association".