Re: Need help building an EOQualifier with session values
Re: Need help building an EOQualifier with session values
- Subject: Re: Need help building an EOQualifier with session values
- From: Mark Morris <email@hidden>
- Date: Tue, 23 May 2006 13:19:50 -0500
Hello Reid,
First of all, I hope your child feels better soon. :-) I have been
through that phase with 3 of my own, so I can empathize.
Ok, let's look at what you have below:
On May 23, 2006, at 12:27 PM, Reid Bundonis wrote:
Ken, Mark, and Chuck,
Thanks for taking the time out of your weekend to help me with the
qualifier statement. So, enough with this WO stuff, anyone have
advice on getting a baby with a cold to sleep? If the rest of this
post in incoherent, I apologize in advance. Sleep deprivation and
WO development do not mix.
First, let me provide a bit more detail about the structure of the
db and what I am trying to do. Reading your posts makes me think
that my thinking is a bit muddled and I am trying to turn something
remarkably simple into something complex and ugly.
First, the database: I have four entities, User (userID [int],
firstName [string], lastName [string], password [string] clientID
[int]), Client (clientID [int], clientName [string]) , Process
(processID [int], processName [string], clientID [int]), and Result
(resultID [int], startTime [date], stopTime [date], processID
[int]). All relationships use a primary and foreign key ints to
create the relationship. Each Client can have many Users but each
user has only one client. Each Client can have many Processes but
each process belongs to only one client, and each Process can have
many Results.
This all seems fine.
Next, what I am trying to accomplish is that when a User logs in,
the User is held in the Session so I can pull unique items out
during the remaining time in the app. For example, when the user
logs in, bind a WOString to session.user.client.clientName or
session.user.firstName, etc. and I have a customized page for the
individual with doing no work other that initiating the session and
storing the logged user there. That is the easy part as on login I
am setting sess.setUser( (User) ... and session has a key for User
to hold the values. From the interface side, this works. I am
able to bind to WOStrings without trouble and the values of the
stored (logged in) User are displayed.
So far, so good.
So, what I was trying to do was on login, since I am storing the
User in session, I assumed that I had access to the full
relationship tree. For example, the WOString binding of
session.user.client.clientName works in the interface and returns
the proper value, so I though I would be able to grab the returned
value and stick it in a qualifier. Thus, when User Bob, who is a
member of Client Prentendco, logs in, I know he is a member of
user.client and the clientName attribute is Prentendco. As
mentioned above, I can display this with WOStrings and binding to
the session.user... attributes. What I would like to do is
dynamically grab the clientName value, as I know it is unique to
each user since the relationship defines one client per user and
then thus pull up a repetition of all the processes that belong to
the user's client. This way, when Bob, of client Pretendco, logs
in, I will get all of Pretendco's processes. When Mary, of
AlterCo, logs in, I will get all of AlterCo's processes, etc. As
Mark pointed out, I should be using the whole object
Right, Ken pointed it out first, but you should just use the object
directly in the qualifier, not an attribute like clientName.
However, in this case you don't even have to go through the step of a
qualifier. You can access the processes simply following the
relationships, as in session.user.client.processes.
Obviously, if I manually set the value, I am good:
NSMutableArray args = new NSMutableArray();
args.addObject("client.clientName");
qual = EOQualifier.qualifierWithQualifierFormat("client.clientName
= 'Pretendco'", args);
fs = new EOFetchSpecification("Process", qual, null);
I want to be able the make the session.user.client.clientName value
and throw it at the qualifier. However, when ever I use the code
suggestion, I get either an attempt to enter a null (see below
regarding Ken's suggestion for println) into the NSArray or I throw
an exception stating that there is no key for
user.client.clientName or anything else.
However, as Ken pointed out with the println statement, I've
discovered I do NOT have access to this value. When trying the
print the line, I throw an exception that the key is unreachable
(lookup of unknown key: 'user.client.clientName'.). If I change
the println statement to valueForKeyPath, then I do not throw the
exception, but instead get a result of null regardless of the key
path. I tried user.firstName (System.out.println("Client name is
"+session().valueForKeyPath("user.firstName"));) as well as the
full path that I think I want, user.client.clientName).
If you're using anything other than a single key (in other words,
there's a path involved), you must use valueForKeyPath.
How is it that I have access to these values through interface
bindings but not programmatically? Am I missing something
remarkably obvious in the session? I am confused that I am able to
access the values through the interface using bindings, but not
programmatically.
You might just want to do a series of println's to see where the
problem really occurs. For instance:
System.out.println( "User = " + session.valueForKey( "user" ) );
System.out.println( "User = " + session.valueForKeyPath
( "user.firstName" ) );
System.out.println( "Client = " + session.valueForKeyPath
( "user.client" ) );
System.out.println( "Client name = " + session.valueForKey
( "user.client.clientName" ) );
Again, thanks everyone for the help and attempts to decode the
ramblings of the sleep deprived.
On May 21, 2006, at 9:51 AM, Ken Anderson wrote:
Reid,
Just so I understand what you want to do - you're trying to fetch
Process records from the database for the client, right?
My first question is, since you say you have a client object, why
are you using the clientName instead of the client object? You
should really have a relationship in Process called 'client',
which is a relationship to the Client entity based on the name (or
better, a unique integer primary key so the client's name can
change without breaking the database).
To address your specific question, are you sure that
user.client.clientName is getting the result you want? Have you
tried:
System.out.println("Client name is "+session().valueForKey
("user.client.clientName"));
Otherwise, if Process has an attribute called 'clientName' that
matches the clientName in the client object, this code should
work. It would help if you gave more information about the model...
Ken
Ken's post has already pointed out how your approach, on the
surface anyway, raises a little warning flag. The code for what
he's talking about would be something like:
NSArray bindings = new NSArray( session().valueForKey
("user.client") );
qual = EOQualifier.qualifierWithQualifierFormat("client = %@",
bindings );
fs = new EOFetchSpecification("Process", qual, null);
You try and store and deal with complete objects when you can, and
in this case EOF will query based on the join attribute you
provided in the (possibly hypothetical) "client" relationship.
Minor points, note that you can construct and NSArray of one
object without going through the Object step, and that you don't
need to cast to Session to use valueForKey. However, if client is
a public variable or (preferably) accessor method in your Session,
you could change that line to:
NSArray bindings = new NSArray( ((Session)session()).user
().client() );
If Bob (in your example) has multiple clients, however, the above
doesn't make sense. If that's the case, and he can choose the
client he's currently dealing with, you could just add a
currentClient variable and accessors (returning a Client object)
to the Session to indicate his choice. Then the code becomes:
NSArray bindings = new NSArray( ((Session)session
()).currentClient() );
qual = EOQualifier.qualifierWithQualifierFormat("client = %@",
bindings );
fs = new EOFetchSpecification("Process", qual, null);
valueForKeyPath not valueForKey
Chuck
So, for your specific issue, it doesn't look like you need to fetch
at all. However, it would be nice to know why you're having trouble
seeing your objects programatically. ;-)
Good luck!
Regards,
Mark
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden