Reputation: 131
I'm trying to find a way to design a set of rails relationships for a billing application. It is for a vendor who receives checks from an insurance company, or payor, and then forwards the payments on to their clients.
The vendor balances checks and payments by the month and sends reports to the client based on activity within that month.
The 'month' however does not directly correspond to the calendar month. Instead the clients are staggered in tiers so that reports are not all due on the same day of the month. For instance, in the month of January a Tier 1 client might have their activity defined as Jan 01-Jan 31, Tier 2 as Jan 07-Feb 06, and so on.
There are exactly 3 tiers.
Each tier has many clients.
A client has many checks.
So far, so straightforward.
I just can't work out how to effectively manage the months:
A check has a deposit date, by which it will belong to a particular 'month'. The month is also necessarily determined by the tier of the check's client.
Since there are three tiers, is follows that there should be three 'January 2013' months, each with different start and end dates, but the uniqueness of 'month-year' and tier should be validated such that tier 1 has exactly one 'January 2013', and so on.
I want the routes to be such that a user can navigate to the clients_path, choose a client, choose a month, and create a new check such that the check knows what month and client it belongs to, and I can't for instance create a new check with a deposit date outside of the range defined by client_month_path.
I think the error I am getting into is perhaps in defining each model as having a has_many or belongs_to relationship, such that a tier has many clients but also many months. But now a check will have two parents, so how do I unite the two?
Upvotes: 0
Views: 54
Reputation: 15515
Interesting question. This answer may not provide an exact answer to your needs and perhaps misses some crucial details, but I hope it can help you.
I think you can solve the 'month-problem' if you stick to some base rules, like:
Those rules will save you from a lot of date shuffling in the rest of your code. If you ever find yourself recalculating what tier-month a check is in, you're doing it wrong. Also, having the tier-month available in every record gives a huge advantage in more complicated queries.
Create methods in the appropriate models (or service objects) for all those business-logic questions. What is the tier date-range for this client in this calendar month? Can this check be dated like that? Do not rely on validation only, sometimes its fine to ask those questions in another context than a save operation, say when rendering a calendar view.
About the queries with two parents. I don't think this is a big problem. In essence you only create an extra WHERE
clause on most queries. For example you can solve that in a controller with a before_filter
that fetches (and perhaps authorizes) the desired client, month and check. These before_filters will only vary slightly across controllers.
I hope this will help a bit.
Upvotes: 2