CakePHP Назначение записей пользователям: подход многократного использования - PullRequest
3 голосов
/ 30 января 2012

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

Iпридумали следующую модель назначения:

Assignment
  -id
  -assignedto_key
  -assignedto_model (either User or Group [hasMany/belongsTo is between User and Group])
  -foreign_key
  -foreign_model

Пока все хорошо.Теперь я хочу иметь возможность назначить любую запись в моем приложении для всей группы или для группы отдельных пользователей.

Например:

Assignment
  -id = 1 (I'm actually using UUIDs)
  -assignedto_key = 1
  -assignedto_model = User (so this would be assigned to User.id = 1)
  -foreign_key = 1
  -foreign_model = Painting

Assignment
  -id = 2 (I'm actually using UUIDs)
  -assignedto_key = 1
  -assignedto_model = Group (so this would be assigned to any User with group_id = 1)
  -foreign_key = 1
  -foreign_model = Painting

Therefore: User 1 can now access the Painting 1. Furthermore, ANY user with group_id = 1 can also access Painting 1.

Пока все хорошо.У меня нет проблем с созданием логики, позволяющей администраторам входить в запись (например, «Живопись») и выбирать группы / пользователей, которые должны это видеть.

Однако там, где я нахожусьпотеря - это когда я хочу отфильтровать данные:

По сути, мне нужно иметь возможность возвращать записи только тем пользователям, к которым у них есть доступ.

В настоящее время я думаю о реализацииэто как поведение, которое я бы прикрепил ко всем моделям, которые являются «Назначаемыми».

public function beforeFind(Model &$model, $query)
{
   // Let's imagine that $model is of type Painting
   // I can only think of the following solution:

   $Assignment = ClassRegistry::init('Assignment');
   $assignedIDs = $Assignment->find('all', array('fields'=> array('id'), 'conditions' => array(
       'Assignment.foreign_model' => $model->alias,
       'or' => array(
                  array('Assignment.foreign_model' => 'User', 'Assignment.foreign_key' => AuthComponent::user('id')),
                  array('Assignment.foreign_model' => 'Group', 'Assignment.foreign_key' => AuthComponent::user('group_id'))
               )
   )));

   $ids = Set::extract('{n}.' . $this->alias . '.id', $assignedIDs);

   $query['conditions'][] = array($this->alias . '.id' => $ids);
}

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

Кто-нибудь может подсказать, как я могу реализовать такую ​​функциональность?

Заранее большое спасибо, и я с нетерпением жду ваших ответов.

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

1 Ответ

1 голос
/ 01 февраля 2012

То, что вы описываете здесь, это «Полиморфные отношения».Чистый DB'er хмурится на них, поскольку отношение закодировано в данных, а не в схеме.Остальные используют их, потому что они работают; -)

Вы видели: http://bakery.cakephp.org/articles/AD7six/2008/03/13/polymorphic-behavior (это поведение 1.3, но переносимое на 2.x).Он выполняет большую часть работы с полиморфными таблицами.

...