2015-01-26 3 views
0

У меня есть набор пользователей, определенных следующим образом:Как выполнить пользовательские настройки конфиденциальности в Метеоре

Accounts.createUser({ 
    username:'Simon', 
    email:'[email protected]', 

    profile:{ 
     firstname:'Simon', 
     lastname:'Surname', 
     location:'Home Address', 

     privacy: { 
      location:0, 
      emails:0 } //Location and emails are private and should not be disclosed 
    } 
}); 

Мой вопрос, как я могу опубликовать запись этого пользователя для других пользователей, чтобы просмотреть, принимая во внимание профиль конфиденциальности настройки. В этом примере я установил неприкосновенность частной жизни для местоположения и адресов электронной почты с нулем, с тем чтобы эта информация не была опубликована для этого пользователя.

Я хотел бы опубликовать его, используя стандартный метод:

Meteor.publish("usersWithPublicEmails", function() { 
    return Meteor.users.find(); 
}); 

Но я не могу видеть способ указать селектор или поля таким образом, что будут опубликованы только публичная информация.

Я пытался добавить дополнительные публикации в виде: но не кажется

Meteor.publish("allUsers", function() { 
    return Meteor.users.find({}, {fields:{username:1}}); 
}); 

Meteor.publish("usersWithPublicEmails", function() { 
    return Meteor.users.find({"profile.privacy.emails":1}, {fields:{username:1, emails:1}}); 
}); 

селектор, чтобы возвращаться электронные письма, как я ожидал. Я ищу оптимальный способ сделать это с точки зрения производительности.

+0

Ммма я получил эту работу, добавив недостающую подписку в моем модуле router.js Однако после добавления дополнительного количества приватности. настройки (включая публикации и подписки) Я вижу некоторые странное поведение с 4 подписок в маршрутизаторе:. \t 'waitOn: функция() { \t \t возвращение Meteor.subscribe ('ALLUSERS') && \t \t \t Meteor.subscribe ('usersWithPublicName') && \t \t \t Meteor.subscribe ('usersWithPublicLocation') && \t \t \t Meteor.subscribe ('usersWithPublicEmails'); \t}, 'Я считаю, что третий не эффективен. Изменение порядка удаляет соответствующие данные со страницы моих пользователей! – Braunius

+0

Я также попытался указать мой waitOn как этот \t 'waitOn: функция() { \t \t возвращение [\t \t \t \t Meteor.subscribe ('ALLUSERS'), \t \t \t Meteor.subscribe ('usersWithPublicName'), \t \t \t Meteor.subscribe ('usersWithPublicLocation'), \t \t \t Meteor.subscribe ('usersWithPublicEmails')]; \t}, 'с теми же результатами. – Braunius

ответ

0

Mongodb не является реляционной базой данных, поэтому всякий раз, когда я хочу присоединиться или запросить на основе метаданных, я помню, что мне нужно делать что-то по-другому. В вашем случае я сделал бы отдельную коллекцию для конфиденциальности пользователей, если бы захотел запросить конфиденциальность пользователя. Кроме того, если бы я заботился о производительности, я бы, вероятно, никогда не захотел бы «все x», я бы просто хотел показать пользователю, таким образом, разбивать страницы. С учетом этих двух идей вы можете легко получить то, что хотите: запрос, основанный на настройках конфиденциальности и производительности.

Privacy = new Mongo.Collection("privacy"); 

Всякий раз, когда мы хотим, чтобы добавить частную жизнь на счет:

Privacy.insert({ 
    emails: 1, 
    userId: account._id, 
}); 

Тогда позже, одна страница в то время, показывая десять результатов каждой страницы, отслеживание currentPage:

Meteor.publish("usersWithPublicEmails function (currentPage) { 
    var results = [] 
    var privacyResults = Privacy.find({"emails":1}, {skip: currentPage, 
     limit: 10}); 
    var result; 
    while (privacyResults.hasNext()) { 
     result = privacyResult.next(); 
     results.append(Meteor.users.find({_id: result.userId}); 
    } 
    return result; 
}); 

Я не тестировал этот код, он может иметь ошибки, но он должен дать вам общую идею. Недостатком здесь является то, что вы должны синхронизировать конфиденциальность и пользователей, но это те проблемы, с которыми вы сталкиваетесь, когда не используете реляционную базу данных.

У Mongodb есть способ сделать этот поиск ссылок с меньшим количеством кода, но он по-прежнему происходит по требованию, и я предпочитаю гибкость в этом. Если вы заинтересованы, посмотрите на Database references

+0

Привет, Бьорн, я выяснил, что случилось в моем случае (отсутствует подписка), но этот совет действительно полезен. Мне было интересно, как ограничить возвращаемые значения, и этот пример действительно полезен. Большое спасибо. – Braunius

+0

Braunius, на StackOverflow вы благодарите с upvotes. ; \ –

+0

Бьорн, я пробовал, но у меня нет достаточной репутации, что кажется странным, но там вы идете. BTW Я обнаружил, что вам нужно использовать privacyResults.forEach для циклического перемещения курсоров. Я не мог найти способ манипулировать значением в наборе записей до его возвращения - что было бы идеально для моего сценария. – Braunius

0

Это потому, что у вас есть опечатка в fields объекте вашего Опубликовать функция, вместо того email вы набрали emails

Так правильная функция будет:

Meteor.publish("usersWithPublicEmails", function() { 
    return Meteor.users.find({"profile.privacy.emails":1}, {fields:{username:1, email:1}}); 
}); 

Кроме того, вы уже публикуете все имена пользователей в своей публикации allUsers, поэтому, чтобы добавить недостающие данные для соответствующих пользователей, вам просто понадобится:

Meteor.publish("usersWithPublicEmails", function() { 
    return Meteor.users.find({"profile.privacy.emails":1}, {fields:{email:1}}); 
}); 

и Meteor автоматически объединяют эти записи для вас.

+0

Привет, Serkan, это не опечатка. Учетные записи Meteor позволяют создавать электронную почту с помощью метода createUser, но сохраняют несколько писем от каждого пользователя. Я ожидал, что метеор объединит записи, как вы говорите, и я удивлен, что этого не происходит. Должно быть, я сделал что-то еще неправильно. Спасибо, что нашли время, чтобы посмотреть на мой вопрос. – Braunius

+0

Привет, Серкан, я отследил его. Мне не хватало соответствующей подписки в предложении waitOn в маршрутизаторе. :-( – Braunius

+0

К сожалению, извините, что я ввел вас в заблуждение. И я рад, что вы это сработали :) –

0

Простое решение в конце. Я пропустил дополнительную подписку на маршрутизаторе:.

Router.route('/users', { 

    name: 'userList', 

    waitOn: function(){ 
     return Meteor.subscribe('allUsers') && 
       Meteor.subscribe('usersWithPublicEmails'); 
    }, 

    data: function(){ 
     return Meteor.users.find(); 
    } 
}); 

Основной ошибка :-(