I would like to be able to create some type of User factory that would
return the correct class based on a type. Basic polymorphism. I'm
haveing trouble adapting this common OO model to transfer.
Would this be the best way to do it?
* Extend the decorator User cfc, creating client.cfc, vendor.cfc
* Create multiple transfer objects (via config): Client, Vendor, etc.
each pointing to the User table (assuming Single Table Inheritance
(STI) right now).
* Add the appropriate decorator to each object
* Create a factory method in a UserService that would return the
correct User subclass based on type?
I'm just thinking out loud. Any other suggestions on how to accomplish
this with transfer?
--Ryan
The short answer to your question is - well, you kinda can't. The
model you've shown is one way of doing it - but that doesn't stop you
from making a Vendor you really mean to be Client through your API.
The long answer to your question really is - this is somewhere where
you should be using Composition, and not Inheritence.
In actuality, all the objects you have are Users, but you are just
doing different things to them, depending on their Type.
Head First Design Patterns actually covers this really, really well.
I woudl say your authentication logic should sit outside the User
object, IMHO, a user doesn't know how to Authenticate, an
Authentication service should know, and it should do the right thing
depending on the type.
Or another way would be to have a Authentication object that you can
add to the User, depending on what the type is, as a comopiste.
I have found that using inheritence in this way leaves you very restricted.
Does that help?
Mark
Without commenting on the composition vs inheritance decision for this
particular example:
This sort of single table inheritance pattern is where a decorator factory
would be handy ;-) But I think there comes a point where you have to admit
that transfer can't implement every domain model, although it could be the
DAO layer for any domain model. It just handles simple Active Record domain
models soooo nicely it's tempting to to keep pushing it.
OTOH, Concrete Table Inheritance works very nicely with decorators.
Jaime
I'm still not quite sure how to implement composition with transfer.
For a slightly different example, how would you go about implementing
a User object composed with an Address object (assuming different db
tables and a 1:1 correlation). Since there is no "onetoone" mapper,
would you use the "onetomany"?
It seems I might be missing something simple...
--Ryan
On the other side, Jaime is correct, doing STI with transfer is a bit
of PITA. It can be done, but you have to manage it well because of
the caching layer.
>
> I'm still not quite sure how to implement composition with transfer.
> For a slightly different example, how would you go about implementing
> a User object composed with an Address object (assuming different db
> tables and a 1:1 correlation). Since there is no "onetoone" mapper,
> would you use the "onetomany"?
You would use a <manytone> mapping in this situation. A 1:1
relationship is really only a a managed m:1 relationship.
Hopefully that makes sense, 'cause we had our xmas party last night,
and my brain isn't working so well.
Mark
The issue is that I have three tables linked by the same key (userID).
If I add the following to my user object:
<manytoone name="Details">
<link to="identity.Contact" column="userID" />
</manytoone>
<manytoone name="Preferences">
<link to="identity.Preference" column="userID"/>
</manytoone>
I get the error upon saving the User because it is trying to add two
userID columns to the update. The only way I've found to get around
this is to use two <onetomany> relationships and override
getDetails(index) with getDetails(), returning the first element, in my
decorator.
The <manytoone> creates the object in the structure I want (basically a
nested object rather than an array) but I just can't save it. Any other
suggestions?
Thanks for your help and patience.
--Ryan
Mark
userLogin table (PK: userID (identity)): has a bunch of login & account fields
userDetail table (PK: userID) has a bunch of personal contact info
fields for a user
userPreference table (PK: userID) has a bunch of app preference fields
for a user
All three are connected by the userID PK and have a 1:1 relationship.
It's not the ideal scenario, but it's what I need to work with.
Does that help?
--Ryan
Looking at this, looks like my other email was correct.
In terms of mapping with Transfer, they either need to be mapped as a
onetomany from UserLogin -> UserDetail, or as a manytoone from
UserDetail->User
That being said - there is no hard and fast rule that says you HAVE to
use composition. You can quite happily have thos foreign keys as
properties, and manage them that way.
Mark