Does anyone know how to "change" field sets in a publication (Meteor.publish or Meteor.publishComposite) based on the certain characteristics/field values of the record with respect to the logged on user?
I was using a publishComposite, with cursors at the same level, like so:
Meteor.publishComposite("games", [
{
find: userRecord,
children: [
{
find: gamesWeArePlaying
}
]
},
{
find: userRecord,
children: [
{
find: gamesWeOwn
}
]
},
{
find: userRecord,
children: [
{
find: examineWithAnalysis
}
]
},
{
find: userRecord,
children: [
{
find: examineWithoutAnalysis
}
]
},
{
find: userRecord,
children: [
{
find: allGames
}
]
}
]);
Each find function returns a cursor with qualifying records, and the field set allowed for that user in that state. Just be aware that in each of the children finds, it will find a set of unique records, but the fields it returns is specific to that cursor. The most common are transitions from "gamesWeArePlaying" to "examineWithAnalysis", and in the case of teacher/student, "examineWithAnalsyis" to "examineWithoutAnalysis."
But what is happening is that when a game (i.e. a single record) transitions from one cursor to another, the underlying framework fails to send correct "changed" fields to the client. The minimongo record(s) get all out of whack, and do not even match what's actually in the servers database.
So, my question is: What is the best way to return, reactively, a set of records, where every single record has a specific field set returned, based on characteristics of said record?
I read through your github code and it seems like your true intention here is to publish all games that this user should have "access" to and you want the user to have different permissions for each of the games. This is more of a
mongodb
solution, you want to have a normal publish(not composite, they are slow and don't work well) where you first get the user ID. Then just query for all the games (as you already are as a composite) like thisThis should retrieve all the games the user should be privy to based on their isolation group or their ownership. I would suggest adding the
isolation_group
even to games you own in order to simplify the query - but that's optional. After you retrieve all these games you'll have them in an array, this is where a library likelodash
comes to our help - you can do a series of_.map()
calls like thisHere is where it becomes a bit tricker, if you publish them as you mentioned with
this.added/changed/removed
to the sameclient side collection
you are bound to get the same game, but you want to show it with specific fields based off of the results of the multiple_.map()
calls. If you add the same game multiple times Meteor will publish the same game multiple times with the different permissions which is not what you want. So modify that map call to actually check for all permissions at once (i.e. gamesWeArePlaying, gamesWeOwn, examineWithAnalysis, ...) and change the_.pick()
list of fields based on that. This will give you a unified array of games with proper fields to publish that will get updated reactively.