3

I have been scouring Apple's Predicate Programming Guide and SO as well, trying to determine the correct way to write a predicate for a certain fetch request.

It seems like the way I am attempting to use dot notation to traverse a relationship is not being respected by the request.

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Task" inManagedObjectContext:context];

[fetchRequest setEntity:entity];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"project.user == %@", self.user];

[fetchRequest setPredicate:predicate];

User, Project, and Task are all core data entities mapping to a BaaS provider (StackMob).

Relationships are as follows: User one-to-many Project one-to-many Task with inverse relationships as you would expect. What I am trying to do is get all tasks for the current logged in user. So, my thinking is: send a fetch request with the entity "Task". Where the project that owns the task is owned by the logged in user, get that task and display it. Simple enough.

And I think I should be able to use the dot notation in the predicate that I have shown above, but the fetch request is returning nil.

Everything else about the fetch request is fine. If I change the format string to @"project != NULL", I get all of the tasks back.

Am I just writing my format string incorrectly? Is dot notation somehow not valid when sending a fetch request to StackMob?

As always, any help is greatly appreciated.

Please let me know if more information is needed. I'm a little too close to this right now to see it clearly.

geraldWilliam
  • 4,123
  • 1
  • 23
  • 35
  • I have no experience with StackMob, but your predicate looks good to me, and dot syntax is definitely allowed in predicates. Are you sure that `self.user` is an instance of the "User" entity? – Martin R Apr 19 '13 at 17:38
  • @Martin R, thanks for your comment. Yes, when I log the predicate to the console, it prints: project.user == (entity: User; id: 0x7c4c1a0 ; data: { projects = ( "0x7d495b0 " ); username = username; usernameId = nil; }) And I was just testing dot notation in a different application with a local data store. Worked fine. – geraldWilliam Apr 19 '13 at 17:45
  • What happens if you fetch all objects and then filter the array using `NSArray *filtered = [results filteredArrayUsingPredicate:predicate]` ? – Martin R Apr 19 '13 at 18:39
  • Yes, that is a valid workaround. Filtering the returned array with the same predicate gives me the result set I want. Querying for all tasks and then filtering them on the client side seems to pose a scalability issue. But this is in prototype stage right now, so maybe that's fine. – geraldWilliam Apr 19 '13 at 18:59
  • 1
    Normally, both methods should work and return the same results. But there was a similar problem a while ago here on SO, where filtering during the fetch did not work. I only remember that in that case also a non-standard backend was used. – Martin R Apr 19 '13 at 19:17
  • @Martin R. Thanks for your assistance. It has been suggested (elsewhere) that I should just give my tasks a user ID instead of traversing the relationship with projects. – geraldWilliam Apr 19 '13 at 19:36
  • As I said, it does work with a "normal" local SQLite based backend. So this might be a special StackMob problem. – Martin R Apr 19 '13 at 19:56

1 Answers1

6

Fetching on an attribute of a relationship (task where project.user == X) is not supported by StackMob. However, it looks like you are trying to get all the tasks for a given project for the logged in user. If I am correct in assuming that the logged in user was the one to create the projects and tasks, then set the permissions of the project schema to "Allow to sm_owner". You can then fetch tasks based on the project ID (task where project IN 1234), or project based on ID and grab all tasks (project where projectId == 1234 and use value of tasks relationship). Either way, with that permission fetches will only return results where sm_owner == logged in user, so you don't need to set up the fetch such that it uses the user ID as a filter. Hope that helps!

msv
  • 163
  • 3