On 2012-03-29, at 3:22 PM, Paul Hoadley wrote:

> 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".  :-)

Sure. Create a custom link component and display it on your list of practices. 
The link has a custom method that sets your selectedPractice on the session in 
thread storage. This way you can access it from the rules as well as your model 
classes or application.

This is a very cool pattern that allows you to do interesting things with 
ERXNavigationMenu, but that's a topic for another day.

Here's an example for selecting a working group from a list:

        public WOComponent view() {
                WorkingGroup selectedWG = (WorkingGroup) object();
                ((Session) session()).setSelectedWG(selectedWG);
                NSArray<Forum> forums = selectedWG.forums();
                Forum aForum = (Forum)forums.lastObject();
                ((Session) session()).setSelectedForum(aForum);
                NSLog.out.appendln("The working group is " + selectedWG);
                return (WOComponent) 
((Session)session()).navController().listMyWGTopics();
        }

the line that sets the selected working group in the session is what you're 
worried about.

and in the session you have code like this:

    protected WorkingGroup _selectedWG;

    public WorkingGroup selectedWG() {
        return _selectedWG;
    }

    public void setSelectedWG(WorkingGroup selectedWG) {
        _selectedWG = selectedWG;
        ERXThreadStorage.takeValueForKey(selectedWG(), "selectedWG");
    }

    public void awake() {
        super.awake();
        
        // if we have a selected working group, keep track of it
        if (selectedWG() != null) {
                ERXThreadStorage.takeValueForKey(selectedWG(), "selectedWG");
        }

    }

    public void sleep() {

        ERXThreadStorage.takeValueForKey(null, "selectedWG");
        super.sleep();
    }

I have methods in the WorkingGroup EO that access the selectedGroup:

  /**
   * Gets the selected working group.
   * 
   * @return selected working group for the thread
   */
  public static WorkingGroup wg() {
    return (WorkingGroup) ERXThreadStorage.valueForKey("selectedWG");
  }

  /**
   * Gets the working group as a local instance in the given context.
   * 
   * @param ec
   *          editing context to pull a local copy of the user into
   * @return user instance in the given editing context
   */
  public static WorkingGroup wg(EOEditingContext ec) {
    WorkingGroup wg = wg();
    if (wg != null && wg.editingContext() != ec) {
      EOEditingContext currentWGEc = wg.editingContext();
      currentWGEc.lock();
      try {
        WorkingGroup localWG = (WorkingGroup) 
ERXEOControlUtilities.localInstanceOfObject(ec, wg);
        wg = localWG;
      }
      finally {
        currentWGEc.unlock();
      }
    }
    return wg;
  }

Here I use the selected Working Group to determine which Forum to assign a 
topic to when it is created:

        public void init(EOEditingContext ec) {
                super.init(ec);
                setTopicDescription("Unspecified Topic Description");
                setTimestampCreation(new NSTimestamp());
                setCreatedByRelationship(Person.currentUser(ec));
                // set the forum for the topic
                WorkingGroup selectedWG = (WorkingGroup) WorkingGroup.wg(ec);
                NSArray forums = selectedWG.forums();
                Forum aForum = (Forum) forums.lastObject();
                setForumRelationship(aForum);
        }


> 
>> Profit? :-)
> 
> Here's hoping.
> 
> 
> -- 
> Paul Hoadley
> http://logicsquad.net/
> 
> 
> 

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

This email sent to arch...@mail-archive.com

Reply via email to