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: Reid Bundonis <email@hidden>
- Date: Tue, 23 May 2006 15:42:22 -0400
Mark and Chuck.
Thanks for the words of empathy. On top of all that, she got her shots
and is teething. Such a poor little thing.
Ok, both of your emails have finally gotten through my thick skull.
And Chuck hit the nail on the head. I was trying to get the values
before they were stored in the session as I was building everything on
the Main component.
I have the login component placed on main and then do a boolean check
to determine if the user can see the rest of the app. But main has
already been called and I had the fetch in super. Thus, since I am
using main for login, when I first get there, all values are null.
Thus null queries. Grumble.
From your suggestions, I finally tried to do the println from another
component. And as you might guess... I can access the values the way
I thought as well as through the shortcuts you both pointed out. So,
it looks like I am on my way. Trying to do too much in the wrong
place.
Gents, as always, I appreciate your assistance to the community and for
helping me get my thinking back on target. Thank you very much.
Reid
On May 23, 2006, at 2:19 PM, Mark Morris wrote:
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