Michael Pavling wrote:
class ShirtProduct < ActiveRecord::Base
end
class PantsProduct < ActiveRecord::Base
end
And have you *really* designed to have a different table for different
types of product? I can only imagine lots of pain that will be caused
by that further down the line.
I'd suggest a look at polymorphism.
My original example is polymorphism using mixin modules/duck typing.
Are you referring to STI? I read a while back that STI was a bad choice
unless your fields are almost the same for every subclass. I am using
sort of a hybrid form of STI as you can see in my current design below.
Can you explain which implementation of polymorphism you were referring
to? In my use case the fields can vary a good bit from type to type,
and the types share about 20% of the fields with the parent class. I am
more concerned about sharing methods than I am fields in these
associations, but I do need to use a parent table to retrieve all
records from every subclass, so I don't have to do a bunch of crazy
joins. My real use case is as follows. If you have 5 minutes to read
my lengthy use case, can you explain which design you would choose and
why?
USE CASE:
I am rewriting some software I use to track affiliate network
transactions and I am going to release it open source, so I want to make
sure the design is sound. The original software was basically a quick
hack written in a day to get some info in my tables. But as I expand my
use of these tables I realize the limitations and I need something that
is designed well and maintainable.
An affiliate network = website that tracks clicks from a publisher
website over to a merchant website and records if a purchase is made.
The affiliate network then records transactions from the merchant
website and makes them available to the publisher so they can see how
much commission they earned from each sale. There are 8 major affiliate
networks that I pull transactions from right now and in the next 5
years, maybe that will grow to 20 or 30... and maybe up to 100 if
someone adds smaller networks to my open source branch.
In the most basic form a transaction (which will be a single
instance/database row of the class) includes a date, a sale amount, and
a commission amount. Each network has a different way of representing
this data and they all include additional fields that are different.
I want to preserve the integrity of the original data from each network
in my database in case I need it later on.. otherwise I would just
manipulate the data when I pull it and insert it into one table with the
common fields (date,sale,commission,network) and drop the rest of the
data. I also need to get the transactions in various formats (csv,xml)
from various sources using REST & SOAP, so each subclass (affiliate
network) will have some custom functionality in grabbing the data. For
these 2 reasons, I was planning on having a separate model and table for
each subclass.
So here is my current design. I created a mixin module called
BaseTransaction for all the shared functionality. Then I have a class
called GeneralTransaction that is an activerecord model. I have a
seperate transaction subclass for each affiliate network...
AffiliateOneTransaction, etc. Each subclass uses the BaseTransaction
mixin module for shared functionality. I am trying to remember, but I
think I chose the mixin module method because I could not use Ruby
inheritence "<" with activerecord and have a seperate table for each
subclass. A GeneralTransaction is inserted every time a subclass record
is inserted and GeneralTransaction has subclass & subclass_id fields to
reference the records in the subclass table. Seems a little bit hairy
to do it this way, but it will work. I am just trying to figure out if
there is a more "correct" way to do this design. Any thoughts and
suggestions are much appreciated. Thanks if you took the time to read
my lengthy post!