# Hasmanythru? Design Query, Willing to make it worthwhile for

**URL:** <https://www.ruby-forum.com/t/hasmanythru-design-query-willing-to-make-it-worthwhile-for/128994>\
**Category:** Rails\
**Created:** [February 13, 2008, 11:01am UTC](https://www.ruby-forum.com/t/hasmanythru-design-query-willing-to-make-it-worthwhile-for/128994 "2008-02-13T11:01:12Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![adityasanghi](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/bbce88/32.png) [@adityasanghi](https://www.ruby-forum.com/u/adityasanghi)\
**Post date:** [February 13, 2008, 11:01am UTC](https://www.ruby-forum.com/t/hasmanythru-design-query-willing-to-make-it-worthwhile-for/128994/1 "2008-02-13T11:01:12Z")

</div>

Hi Guys,

Looking for help on a design issue! Not looking for free help either.

So the help i need is around polymorphic associations.

I have an app where the customer’s “case” model has to be associated  
with ONE rateplan.  
The Rateplan model can be on many types and are predefined by the system  
owners. I currently have a rake task to load up all the rateplans (later  
i’ll provide an admin interface).  
For modelling the Rateplan types i used Single Table Inheritance.

The case form will have a select box of rateplans to choose from.  
So far…

[code=]class Case \< ActiveRecord::Base  
belongs\_to :rateplan  
end

class Rateplan \< ActiveRecord::Base  
has\_many :cases  
end

class SimpleRateplan \< Rateplan  
end

class FlexRateplan \< Rateplan  
end

class FunkyComplexRateplan \< Rateplan  
end[/code] ([Parked at Loopia](http://pastie.caboo.se/151447))

Now the complexity is that depending on the type of rateplan chosen  
there are some fields that need to be provided by the case for e.g. if a  
FlexRateplan is chosen a number of parameters can be provided by the  
customer when creating the case. So, I’m having difficulty trying to  
implement methods that need to work on the case. I know the relationship  
between Case and Rateplan is polymorphic (depending the on the type of  
rateplan picked).

Thus after design 2.0 , I came up with

[code=]class Case \< ActiveRecord::Base  
has\_one :case\_rateplan  
end

class CaseRateplan \< ActiveRecord::Base  
belongs\_to :case  
belongs\_to :rateplan  
end

class Rateplan \< ActiveRecord::Base  
has\_many :case\_rateplans  
has\_many :cases , :through =\> :case\_rateplans  
end

class SimpleRateplan \< Rateplan  
end

class FlexRateplan \< Rateplan  
end

class FunkyComplexRateplan \< Rateplan  
end[/code] ([Parked at Loopia](http://pastie.caboo.se/151448))  
and after another iteration it started looking like

[code=]class Case \< ActiveRecord::Base  
has\_one :case\_rateplan

def use\_calc  
# use case\_rateplan.calc  
end

end

class CaseRateplan \< ActiveRecord::Base  
belongs\_to :case  
end

class SimpleCaseRateplan \< CaseRateplan  
belongs\_to :case  
belongs\_to :simple\_rateplan

def calc  
# read mostly rateplan fields  
# read some case fields  
end  
end

class FlexCaseRateplan \< CaseRateplan  
belongs\_to :flex\_rateplan

def calc  
# read some rateplan fields  
# read some case fields  
end  
end

class FunkyComplexCaseRateplan \< CaseRateplan  
belongs\_to :funky\_complex\_rateplan

def calc  
# read a few rateplan fields  
# read a number of case fields  
end  
end

class Rateplan \< ActiveRecord::Base  
has\_many :case\_rateplans  
has\_many :cases , :through =\> :case\_rateplans  
end

class SimpleRateplan \< Rateplan  
end

class FlexRateplan \< Rateplan  
end

class FunkyComplexRateplan \< Rateplan  
end[/code] ([Parked at Loopia](http://pastie.caboo.se/151449))  
The association table models could access the rateplan fields as well as  
the case fields. But things have started to look fubar.

Looking for design guidance.

I’m not afraid to go and read, so point me to a good reference doc or  
app (i’ll read the code). I’m of course willing to shell out some money  
(Paypal?) and recommend (WorkingWithRails?) if someone is kind of enough  
to provide appropriate and detailed guidance.

Cheers,  
Aditya

P.S.: Please don’t ask me to Google it (BTDT).  
MySkillLevel: Definitely NOT a newbie; Definitely not a master!

---

<div class="post-metadata">

**Author:** ![adityasanghi](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/bbce88/32.png) [@adityasanghi](https://www.ruby-forum.com/u/adityasanghi)\
**Post date:** [February 13, 2008, 12:23pm UTC](https://www.ruby-forum.com/t/hasmanythru-design-query-willing-to-make-it-worthwhile-for/128994/2 "2008-02-13T12:23:31Z")

</div>

Cheers,  
Aditya

---

<div class="post-metadata">

**Author:** ![adityasanghi](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/bbce88/32.png) [@adityasanghi](https://www.ruby-forum.com/u/adityasanghi)\
**Post date:** [February 14, 2008, 2:34pm UTC](https://www.ruby-forum.com/t/hasmanythru-design-query-willing-to-make-it-worthwhile-for/128994/3 "2008-02-14T14:34:43Z")

</div>

Hi,

As I understand it, depending on the level of rate plan that a user  
selects, the user will need to provide different levels of  
information. I would probably do as follows:

For the Case model, define every single parameter that is required so  
that there is one table for your cases. From a view perspective, you  
would probably need to use Javascript to present the correct inputs  
depending on the plan selected.

I would then create a RatePlan model defining the varying rate plans  
that you offer. I assume these all have common features.

I would then create an intermediate Subscriptions model so a Case  
has\_one subscription and the subscription belongs\_to one RatePlan.  
This would be to ensure a resource based approach to my application  
e.g. create subscription, update subscription etc.

You would then end up with:

def Case \< ActiveRecord::Base  
has\_one :subscription  
has\_one :rate\_plan, :through =\> :subscription  
end

def Subscription \< ActiveRecord::Base  
belongs\_to :case  
belongs\_to :rate\_plan  
end

def RatePlan \< ActiveRecord::Base  
has\_many :subscriptions  
end

I created something similar for an app I’m working on at the moment  
but don’t have access to the files at the moment. I think the  
associations above are correct and hope they help.

Robin

On Feb 13, 11:23 am, Aditya S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![adityasanghi](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/bbce88/32.png) [@adityasanghi](https://www.ruby-forum.com/u/adityasanghi)\
**Post date:** [February 14, 2008, 2:54pm UTC](https://www.ruby-forum.com/t/hasmanythru-design-query-willing-to-make-it-worthwhile-for/128994/4 "2008-02-14T14:54:07Z")

</div>

Robin F. wrote:

> Hi,
> 
> As I understand it, depending on the level of rate plan that a user  
> selects, the user will need to provide different levels of  
> information. I would probably do as follows:

Totally correct. The rateplan provides certain attributes but some are  
flexible, so the case form captures the bits which are flexible.

> For the Case model, define every single parameter that is required so  
> that there is one table for your cases. From a view perspective, you  
> would probably need to use Javascript to present the correct inputs  
> depending on the plan selected.  
> Yup, the UI part is clear to me! But i suppose what would be nice is to  
> dynamically be able to identify the Rateplan “type” can render the  
> partial based on model’s type. So, SimpleRateplan would render  
> simplerateplan/\_case\_rp\_form.html.erb and ComplexRateplan would render  
> complexrateplan/\_case\_rp\_form.html.erb

Meaning the views are dynamically picked based on the inherited model.  
Haven’t seen that as yet! Or dont know how as yet.

> I would then create a RatePlan model defining the varying rate plans  
> that you offer. I assume these all have common features.  
> Not exactly, the rateplan “types” differ a fair bit. But not enough not  
> to  
> implement STI. I’ve got about 4 classes inheriting from Rateplan.

> I would then create an intermediate Subscriptions model so a Case  
> has\_one subscription and the subscription belongs\_to one RatePlan.  
> This would be to ensure a resource based approach to my application  
> e.g. create subscription, update subscription etc.

> You would then end up with:
> 
> def Case \< ActiveRecord::Base  
> has\_one :subscription  
> has\_one :rate\_plan, :through =\> :subscription  
> end  
> Now, has\_one :through does not exist. I need to hack it in from what  
> i’ve been told on IRC. Someone suggested I build a plugin to support  
> this. There is another unverified sample code on the RailsWiki. Frankly,  
> I don’t understand it enough to make this change as yet. But if need be,  
> i’ll do it.

> def Subscription \< ActiveRecord::Base  
> belongs\_to :case  
> belongs\_to :rate\_plan  
> end
> 
> def RatePlan \< ActiveRecord::Base  
> has\_many :subscriptions  
> end

My problem is that the fields that i need to do calculations on are  
based on Rateplan’s type (they need to read fields from the case as well  
as the rateplan). So i’ll need to do parallel subclassing/inheritance on  
the Subscription as well. (Parallel to Rateplan’s subclassing). This is  
getting ugly right? Probably not the best design, or is it? 🙂

Thanks heaps for your help Robin. If you’ve got a favourite charity or a  
paypal account, i’m happy to chip in a token amount!

Cheers,  
Aditya
