D2W: Pattern for complex object creation

3 views
Skip to first unread message

Paul Hoadley

unread,
Mar 29, 2012, 5:31:39 AM3/29/12
to WebObjects Development
Hello,

Here's some background, medium-length only because it's slightly interesting in itself.  Some years ago now, in my pre-WebObjects phase, I needed an application to implement a really simple model for billing time and creating invoices.  Not knowing any better, I picked up a book on Ruby on Rails, and made a very basic web application, relying largely on what Rails calls "scaffolding", which is somewhat reminiscent of D2W.  The app had some minimally customised controller classes, and that was it.  I've been using it for about 6 years.  Having no interest in maintaining or updating the app, or keeping up with Ruby or Rails, though, the app breaks with every OS X upgrade (because Ruby and/or Rails changes).  Previously I've jumped in and fixed the broken bits, but I can no longer be bothered.  Yesterday I figured I would see how long it takes to create an ERModern D2W application from the existing database.  Answer: 13 minutes.  Admittedly I knew what I was doing, but it took me 13 minutes to reverse engineer a model and bring up a basic D2W application, and several of those were spent downloading the MySQL JDBC driver, and discovering "zeroDateTimeBehavior=convertToNull".  13 minutes—that's pretty cool.

Anyway, the subject above is probably a misnomer: I'm not trying to create particularly complex objects, but I am trying to do something outside CRUD, which is pretty much all I've ever done with D2W before.  In the model, a Billable object has an optional to-one relationship to Invoice.  When I create a Billable, it initially has no related Invoice.  Later I will create an Invoice for a client, and collect together some set of Billables, and the relationship is created at that time.  And that's the bit I need a pattern for: Invoice creation.  Billable also has a mandatory relationship to Practice (i.e., a client), and a startTime timestamp.  When I go to create an Invoice, I'd give the Invoice a date and select a Practice, and then I want to add, say, all of the Billables that (a) belong to no other Invoice, (b) point to the same Practice, and (c) have a startTime that falls before the new Invoice.date.

My first thought was to create tabs on the wizard creation page for Invoice, such that I set the date and Practice in the first tab, and then on the next tab I get the billables relationship pre-populated with the Billables that match the criteria above.  Is this the approach?  And if so, in which method do I select those Billables and add them—Invoice.setDate(), or Invoice.setPractice() seemed like candidates, but (a) I need both of those to be set before selecting the Billables, and (b) I only want this for new object creation.  I actually think I can do it, but it seemed like a bit of work, so I figured it would be a good place to pause and see whether this is the right pattern anyway.

What do other people do?  Any comments would be appreciated.


-- 
Paul Hoadley
http://logicsquad.net/



Henrique Gomes

unread,
Mar 29, 2012, 6:26:31 AM3/29/12
to Paul Hoadley, WebObjects Development

On Mar 29, 2012, at 10:31 AM, Paul Hoadley wrote:

> the app breaks with every OS X upgrade (because Ruby and/or Rails changes).

Thanks for the (implicit) warning :-) I'll stay clear of that framework.

Slightly more serious; is it really an intrinsic problem of Rails, or just your app?

Henrique Gomes


_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (Webobje...@lists.apple.com)
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/webobjects-dev/webobjects-dev-garchive-31333%40googlegroups.com

This email sent to webobjects-dev...@googlegroups.com

Pascal Robert

unread,
Mar 29, 2012, 6:33:29 AM3/29/12
to Henrique Gomes, WebObjects Development

Le 2012-03-29 à 06:26, Henrique Gomes a écrit :

>
> On Mar 29, 2012, at 10:31 AM, Paul Hoadley wrote:
>
>> the app breaks with every OS X upgrade (because Ruby and/or Rails changes).
>
> Thanks for the (implicit) warning :-) I'll stay clear of that framework.
>
> Slightly more serious; is it really an intrinsic problem of Rails, or just your app?

I don't use Ruby, but I did see many times people saying that often big "releases" breaks stuff become the top developers want to "fix things" and expect everyone to do the same.

Paul Hoadley

unread,
Mar 29, 2012, 6:52:21 AM3/29/12
to Henrique Gomes, WebObjects Development
On 29/03/2012, at 8:56 PM, Henrique Gomes wrote:

> On Mar 29, 2012, at 10:31 AM, Paul Hoadley wrote:
>
>> the app breaks with every OS X upgrade (because Ruby and/or Rails changes).
>
> Thanks for the (implicit) warning :-) I'll stay clear of that framework.
>
> Slightly more serious; is it really an intrinsic problem of Rails, or just your app?

The short answer is that I don't know, because I learned just enough Ruby and RoR to get that app running, and then stopped. But given that the app did _almost_ nothing more than basic CRUD operations using RoR "scaffolding" (think D2W), I'd say the problem is Rails. Never anything major, usually just breakage due to API changes. But certainly something that you don't see with WebObjects and the ability to embed everything for deployment. (Although this Rails app just ran on my laptop, it was "deployed" in the sense that I just wanted it to keep running.)


--
Paul.

http://logicsquad.net/

David LeBer

unread,
Mar 29, 2012, 8:21:53 AM3/29/12
to Paul Hoadley, WebObjects Development
Don't you DARE equate ROR scaffolding with D2W, just, dont... grr... I...

...gotta go punch a helpless stuffed bunny now...

;-)

--
David LeBer
Codeferous Software

> https://lists.apple.com/mailman/options/webobjects-dev/dleber_wodev%40codeferous.com
>
> This email sent to dleber...@codeferous.com

Ramsey Gurley

unread,
Mar 29, 2012, 11:51:35 AM3/29/12
to Paul Hoadley, WebObjects Development

On Mar 29, 2012, at 2:31 AM, Paul Hoadley wrote:

> Anyway, the subject above is probably a misnomer: I'm not trying to create particularly complex objects, but I am trying to do something outside CRUD, which is pretty much all I've ever done with D2W before. In the model, a Billable object has an optional to-one relationship to Invoice. When I create a Billable, it initially has no related Invoice. Later I will create an Invoice for a client, and collect together some set of Billables, and the relationship is created at that time. And that's the bit I need a pattern for: Invoice creation. Billable also has a mandatory relationship to Practice (i.e., a client), and a startTime timestamp. When I go to create an Invoice, I'd give the Invoice a date and select a Practice, and then I want to add, say, all of the Billables that (a) belong to no other Invoice, (b) point to the same Practice, and (c) have a startTime that falls before the new Invoice.date.

Well, you can just set the practice, the invoice date, and then save changes. In Invoice.willInsert() fetch the billables and add them to the relationship just before the save takes place. :-) Or is that too automatic?

Ramsey

David Holt

unread,
Mar 29, 2012, 1:41:36 PM3/29/12
to Ramsey Gurley, WebObjects Development
Hi Paul,

On 2012-03-29, at 8:51 AM, Ramsey Gurley wrote:

>
> On Mar 29, 2012, at 2:31 AM, Paul Hoadley wrote:
>
>> Anyway, the subject above is probably a misnomer: I'm not trying to create particularly complex objects, but I am trying to do something outside CRUD, which is pretty much all I've ever done with D2W before. In the model, a Billable object has an optional to-one relationship to Invoice. When I create a Billable, it initially has no related Invoice. Later I will create an Invoice for a client, and collect together some set of Billables, and the relationship is created at that time. And that's the bit I need a pattern for: Invoice creation. Billable also has a mandatory relationship to Practice (i.e., a client), and a startTime timestamp. When I go to create an Invoice, I'd give the Invoice a date and select a Practice, and then I want to add, say, all of the Billables that (a) belong to no other Invoice, (b) point to the same Practice, and (c) have a startTime that falls before the new Invoice.date.
>
> Well, you can just set the practice, the invoice date, and then save changes. In Invoice.willInsert() fetch the billables and add them to the relationship just before the save takes place. :-) Or is that too automatic?

I would probably do it in my Invoice init() method.

Get the practice from thread storage (assuming you select it somehow and can save it in thread storage at that point)
Set the date to current time
Fetch billables that match your criteria
Set the relationship to billables.

Profit? :-)

David

>
> Ramsey
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Webobjects-dev mailing list (Webobje...@lists.apple.com)
> Help/Unsubscribe/Update your Subscription:

> https://lists.apple.com/mailman/options/webobjects-dev/programmingosx%40mac.com
>
> This email sent to program...@mac.com

Paul Hoadley

unread,
Mar 29, 2012, 6:20:36 PM3/29/12
to Ramsey Gurley, WebObjects Development
Hi Ramsey,

On 30/03/2012, at 2:21 AM, Ramsey Gurley wrote:

On Mar 29, 2012, at 2:31 AM, Paul Hoadley wrote:

Anyway, the subject above is probably a misnomer: I'm not trying to create particularly complex objects, but I am trying to do something outside CRUD, which is pretty much all I've ever done with D2W before.  In the model, a Billable object has an optional to-one relationship to Invoice.  When I create a Billable, it initially has no related Invoice.  Later I will create an Invoice for a client, and collect together some set of Billables, and the relationship is created at that time.  And that's the bit I need a pattern for: Invoice creation.  Billable also has a mandatory relationship to Practice (i.e., a client), and a startTime timestamp.  When I go to create an Invoice, I'd give the Invoice a date and select a Practice, and then I want to add, say, all of the Billables that (a) belong to no other Invoice, (b) point to the same Practice, and (c) have a startTime that falls before the new Invoice.date.

Well, you can just set the practice, the invoice date, and then save changes. In Invoice.willInsert() fetch the billables and add them to the relationship just before the save takes place. :-)  Or is that too automatic?

It's more automatic than I was thinking, but it sounds alright.  Say if I wanted to review the list of Billables before saving, though, what would you do then?

Paul Hoadley

unread,
Mar 29, 2012, 6:22:43 PM3/29/12
to David Holt, WebObjects Development
Hi David,

On 30/03/2012, at 4:11 AM, David Holt wrote:

On 2012-03-29, at 8:51 AM, Ramsey Gurley wrote:


On Mar 29, 2012, at 2:31 AM, Paul Hoadley wrote:

Anyway, the subject above is probably a misnomer: I'm not trying to create particularly complex objects, but I am trying to do something outside CRUD, which is pretty much all I've ever done with D2W before.  In the model, a Billable object has an optional to-one relationship to Invoice.  When I create a Billable, it initially has no related Invoice.  Later I will create an Invoice for a client, and collect together some set of Billables, and the relationship is created at that time.  And that's the bit I need a pattern for: Invoice creation.  Billable also has a mandatory relationship to Practice (i.e., a client), and a startTime timestamp.  When I go to create an Invoice, I'd give the Invoice a date and select a Practice, and then I want to add, say, all of the Billables that (a) belong to no other Invoice, (b) point to the same Practice, and (c) have a startTime that falls before the new Invoice.date.

Well, you can just set the practice, the invoice date, and then save changes. In Invoice.willInsert() fetch the billables and add them to the relationship just before the save takes place. :-)  Or is that too automatic?

I would probably do it in my Invoice init() method.

Get the practice from thread storage (assuming you select it somehow and can save it in thread storage at that point)
Set the date to current time
Fetch billables that match your criteria
Set the relationship to billables.

Yeah, OK, and then the billables relationship would be editable before I save the Invoice.  Now, humour me—give me an example of how I can "select it somehow and save it in thread storage".  :-)

Profit? :-)

Here's hoping.

Ramsey Gurley

unread,
Mar 29, 2012, 7:23:02 PM3/29/12
to Paul Hoadley, WebObjects Development
More than one way to skin a cat here.  I'd probably just set up a wizard.

step 1, choose a practice with an ERD2WEditToOneRelationship that filters the list to only practices with billables that have no invoice.
step 2, choose billables form a filtered list for that practice with an ERD2WEditToManyRelationship component.
step 3, edit invoice date
validate and save accordingly

Ramsey


_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      (Webobje...@lists.apple.com)
Help/Unsubscribe/Update your Subscription:

David Holt

unread,
Mar 29, 2012, 7:27:59 PM3/29/12
to Ramsey Gurley, WebObjects Development
On 2012-03-29, at 4:23 PM, Ramsey Gurley wrote:

More than one way to skin a cat here.  I'd probably just set up a wizard.

step 1, choose a practice with an ERD2WEditToOneRelationship that filters the list to only practices with billables that have no invoice.
step 2, choose billables form a filtered list for that practice with an ERD2WEditToManyRelationship component.

Can you use information entered in Step one to inform step two?

step 3, edit invoice date
validate and save accordingly

Ramsey


On Mar 29, 2012, at 3:20 PM, Paul Hoadley wrote:

Hi Ramsey,

On 30/03/2012, at 2:21 AM, Ramsey Gurley wrote:

On Mar 29, 2012, at 2:31 AM, Paul Hoadley wrote:

Anyway, the subject above is probably a misnomer: I'm not trying to create particularly complex objects, but I am trying to do something outside CRUD, which is pretty much all I've ever done with D2W before.  In the model, a Billable object has an optional to-one relationship to Invoice.  When I create a Billable, it initially has no related Invoice.  Later I will create an Invoice for a client, and collect together some set of Billables, and the relationship is created at that time.  And that's the bit I need a pattern for: Invoice creation.  Billable also has a mandatory relationship to Practice (i.e., a client), and a startTime timestamp.  When I go to create an Invoice, I'd give the Invoice a date and select a Practice, and then I want to add, say, all of the Billables that (a) belong to no other Invoice, (b) point to the same Practice, and (c) have a startTime that falls before the new Invoice.date.

Well, you can just set the practice, the invoice date, and then save changes. In Invoice.willInsert() fetch the billables and add them to the relationship just before the save takes place. :-)  Or is that too automatic?

It's more automatic than I was thinking, but it sounds alright.  Say if I wanted to review the list of Billables before saving, though, what would you do then?


-- 
Paul Hoadley
http://logicsquad.net/



_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      (Webobje...@lists.apple.com)
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/webobjects-dev/rgurley%40smarthealth.com

This email sent to rgu...@smarthealth.com

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list      (Webobje...@lists.apple.com)
Help/Unsubscribe/Update your Subscription:

Ramsey Gurley

unread,
Mar 29, 2012, 7:57:31 PM3/29/12
to David Holt, WebObjects Development
On Mar 29, 2012, at 4:27 PM, David Holt wrote:


On 2012-03-29, at 4:23 PM, Ramsey Gurley wrote:

More than one way to skin a cat here.  I'd probably just set up a wizard.

step 1, choose a practice with an ERD2WEditToOneRelationship that filters the list to only practices with billables that have no invoice.
step 2, choose billables form a filtered list for that practice with an ERD2WEditToManyRelationship component.

Can you use information entered in Step one to inform step two?

Sure. Just set the restrictedChoiceKey to resolve to a method on the EO.  Something like object.billablesForCurrentPracticeWithoutInvoice.  Then use the practice set in step one to filter the list for step 2.

Paul Hoadley

unread,
Mar 29, 2012, 7:57:32 PM3/29/12
to WebObjects Development
Hi guys,

David, I'll look at your solution shortly, but Ramsey's here was closer to what I was envisaging.

On 30/03/2012, at 9:57 AM, David Holt wrote:

On 2012-03-29, at 4:23 PM, Ramsey Gurley wrote:

More than one way to skin a cat here.  I'd probably just set up a wizard.

step 1, choose a practice with an ERD2WEditToOneRelationship that filters the list to only practices with billables that have no invoice.

I would move Step 3 into Step 1, only because I want the date to be part of the filter on Billables.  (I might be running a couple of days behind on the Invoice, and already have new Billables for the current month.  It really needs another "cutoff date" attribute, probably doesn't even need to be persisted, as opposed to the "date on the invoice".  But that's a detail I can work out.)

step 2, choose billables form a filtered list for that practice with an ERD2WEditToManyRelationship component.

Oh, OK, I was thinking about it incorrectly for some reason, figuring I had to populate the Billables relationship from within Invoice itself after date and practice had been set.

Can you use information entered in Step one to inform step two?

Presumably I've set Invoice.date and Invoice.practice in Step 1, and I can use those values in Step 2?  I'll try it and report back.


Ramsey Gurley

unread,
Mar 29, 2012, 8:00:33 PM3/29/12
to Paul Hoadley, WebObjects Development
On Mar 29, 2012, at 4:57 PM, Paul Hoadley wrote:

Hi guys,

David, I'll look at your solution shortly, but Ramsey's here was closer to what I was envisaging.

On 30/03/2012, at 9:57 AM, David Holt wrote:

On 2012-03-29, at 4:23 PM, Ramsey Gurley wrote:

More than one way to skin a cat here.  I'd probably just set up a wizard.

step 1, choose a practice with an ERD2WEditToOneRelationship that filters the list to only practices with billables that have no invoice.

I would move Step 3 into Step 1, only because I want the date to be part of the filter on Billables.  (I might be running a couple of days behind on the Invoice, and already have new Billables for the current month.  It really needs another "cutoff date" attribute, probably doesn't even need to be persisted, as opposed to the "date on the invoice".  But that's a detail I can work out.)

Yeah, if date makes sense first, then that's better. You can then filter your practice list by date, then your billables list by practice and date. Both toOne and toMany components look for a restrictedChoiceKey.

Tim Worman

unread,
Mar 29, 2012, 8:18:18 PM3/29/12
to Ramsey Gurley, WebObjects Development
I love reading stuff like this - really useful. Every time I try to use D2W I get a certain distance into it and then feel as as if I'd be faster developing a standard WO app than navigating a whole new manner of thinking (and composing rules). Figuring out how to make a D2W app flexible has been hard for me to wrap my head around.

Thanks for the great ideas!

Tim

> https://lists.apple.com/mailman/options/webobjects-dev/lists%40thetimmy.com
>
> This email sent to li...@thetimmy.com


_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (Webobje...@lists.apple.com)
Help/Unsubscribe/Update your Subscription:

Ramsey Gurley

unread,
Mar 29, 2012, 8:48:43 PM3/29/12
to Tim Worman, WebObjects Development
Come to WOWODC. David and I will be doing a D2W lab. It will be a perfect opportunity to ask questions about D2W flow and such :-)

Ramsey

Paul Hoadley

unread,
Mar 29, 2012, 8:56:27 PM3/29/12
to Ramsey Gurley, WebObjects Development
On 30/03/2012, at 10:30 AM, Ramsey Gurley wrote:

More than one way to skin a cat here.  I'd probably just set up a wizard.

step 1, choose a practice with an ERD2WEditToOneRelationship that filters the list to only practices with billables that have no invoice.

I would move Step 3 into Step 1, only because I want the date to be part of the filter on Billables.  (I might be running a couple of days behind on the Invoice, and already have new Billables for the current month.  It really needs another "cutoff date" attribute, probably doesn't even need to be persisted, as opposed to the "date on the invoice".  But that's a detail I can work out.)

Yeah, if date makes sense first, then that's better. You can then filter your practice list by date, then your billables list by practice and date. Both toOne and toMany components look for a restrictedChoiceKey.

Working as intended—thanks Ramsey.

I'm currently using ERD2WEditToOneRelationship (as a popup for the Practice), and ERD2WEditToManyRelationship (as a browser for the Billables).  Are there ERModern variants that will also work with restrictedChoiceKey like this?


David Holt

unread,
Mar 29, 2012, 9:51:58 PM3/29/12
to Ramsey Gurley, WebObjects Development
I just may ask some myself ;-)

Sent from my iPad

Tim Worman

unread,
Mar 30, 2012, 1:36:07 PM3/30/12
to David Holt, WebObjects Development
I really wish I could come but my employer definitely will not pay for it.

Tim

Reply all
Reply to author
Forward
0 new messages