Как я могу построить отношение «имеет много сквозных», связывающее более двух моделей? - PullRequest
3 голосов
/ 02 октября 2011

У меня есть 3 модели, например;

TABLE `users`
    `id` INT
    `username` VARCHAR(32)
    ...

TABLE `books`
    `id` INT
    `title` VARCHAR(100)
    `author` INT (foreign ket constraint)

TABLE `rights`
    `id` INT
    `name` VARCHAR(32)

Теперь я хочу, чтобы у пользователя были определенные права, например. читать или редактировать книгу. Таким образом, таблица прав должна выглядеть так же, как таблица ролей ORM:

|----|------|
| id | name |
|----|------|
| 1  | view |
| 2  | edit |
| .. | ...  |

И у меня будет четвертая таблица, связывающая все три;

TABLE user_book_rights
|---------|---------|----------|
| user_id | book_id | right_id |
|---------|---------|----------|
|    1    |    1    |    2     |
|    1    |    2    |    1     |
|    2    |    1    |    1     |
|   ...   |   ...   |   ...    |

Так что, если пользователь хочет, скажем, прочитать книгу, я хочу проверить, имеет ли авторизованный пользователь с идентификатором 1 право на идентификатор 1 для книги с идентификатором 2.

Но как, черт возьми, я могу добиться этого с помощью ORM? Конечно, я могу написать свой собственный запрос;

SELECT COUNT(*) as `has_right` FROM `user_book_rights` WHERE user_id=1 AND book_id=2 AND right_id=1

if($result['has_right']) {
    echo 'Yeah, read the book!';
} else {
    echo 'Sorry mate, this book is not for dummies...';
}

Но я бы предпочел сделать что-то вроде:

$has_right = $user->has('book_rights', ORM::factory('user_book_right', array('book_id' => '2', 'right_id' => 1));

Или еще лучше:

$book = ORM::factory('book', 1);
$right = ORM::factory('right', array('name' => 'view'));
$has_right = $user->has('book_rights', ORM::factory('user_book_right', array($book, $right)));

Я не смог найти ответ на свой вопрос. Странно ли хотеть связать три модели как многострадальную реальность? Или ORM просто не способен, и я должен написать свой собственный запрос?

Спасибо, в том числе. для вашего понимания!

1 Ответ

1 голос
/ 04 октября 2011

Может быть, мой ответ вам не сильно поможет.Но я предлагаю вам закодировать право в битовом представлении.

READ = 00000001 = 1
EDIT = 00000010 = 2
DELETE = 0000100 = 4

, чем, если у пользователя есть запись для чтения, редактирования и удаления, просто выполните

READ | EDIT | DELETE = 0000111 = 7

Если вы хотитечтобы проверить, имеет ли пользователь конкретное право, которое вы просто делаете: if ($ user_write & READ) {// он может читать}

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

...