Hasmanythru? Design Query, Willing to make it worthwhile for

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] (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] (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] (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!

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