I’ve really enjoyed using contexts to organize and protect my business logic from the web app. I’m attempting to more fully decouple my contexts though and wanted to check with others to make sure I’m not going to down a bad path.
I’m building an app to manage shared office suite buildings. There are more contexts than this, but let’s focus on the following four:
Accounts - Users and Profiles, Authentication
CompanyMgmt - Companies can lease multiple spaces in our buildings and a company can have multiple users
Inventory - Locations, Offices, Conference Rooms, Spaces (like first floor), office types (salon, focus, coworking, etc.)
Calendar - Reservations - Members can reserve conference rooms
I’ve previously tried to keep these somewhat decoupled by allowing for cross-context belongs_to relationships, but no has_one/has_many. I’d like to remove all cross-context relationships.
Let’s take the “Calendar” context as an example since it is intertwined with a lot of other contexts.
There is a calendar for each of our building’s locations. Any company with the lease of a suite in that building gets 20/hrs/mo of free time to reserve space. If they have multiple leases, they’ll get more time.
Each location has about four conference rooms and depending upon the size, different rooms may count more against allotted monthly hours.
Companies have multiple users and the time reserved by the users is pooled together against the allotment.
All in all, there are the following cross-context dependencies in the “Calendar” context:
Inventory.Room - Rooms are pulled directly from the Inventory context. Reservations have a belongs_to room association.
Accounts.User - Reservations have a belongs_to user association.
Inventory.Location - Each location has a calendar. These locations are directly from the Inventory context.
CompanyMgmt.Company - There is no direct association between companies and reservations, but users have reservations and companies have users. I need to let users know how many hours their company has left and reporting on usage by company.
To fully realize the benefits of decoupled contexts, I originally thought that I would need to have a separate table for each of calendar users, rooms, locations, and companies. This would be much like the concept of an “author” record in a blog. This seemed like a ton of work. However, I realized that I can just create separate schemas for each of these entities in the Calendar context using the same table as the schemas in the other contexts. I can even have the exact same associations, only they now associate to the Calendar-specific schemas. This means that none of my queries (including preloads, joins, etc.) needed to change at all.
This allows me to remove a few calendar-specific attributes from other contexts.
This brings me to my questions:
- All in all, this was an extremely simple refactoring to the point that I’m wondering if it is so easy that I am missing issues this might cause me down the road. Are there problems this might cause me in the future?
- Is this the “go to” way to handle this sort of thing in cases where “all” of the records for a given table are relevant to a given context.
- I’ve previously tried to avoid throwing a bunch of extra columns on to a given table for different use cases. For example, if there were 50 different company settings for different scenarios (like calendar usage), I would probably break those into different tables to, if nothing else, avoid accidentally loading all of those settings up when grabbing a company record. However, different schemas ensure that only the specified attributes are ever selected. Thus, there doesn’t seem to be much of a downside to dumping a bunch of columns into one table. Any disagreements on that point?