CakePHP 2.0 твиттероподобная кнопка следования

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

Что мне нужно:

Твиттероподобный follow кнопка с action следовать за пользователем.

Что я уже сделал:

База данных

users таблица: идентификатор, имя пользователя, пароль,...

users_users table: id, user_id, follower_id

Код

В модели User.php

public $hasAndBelongsToMany = array(
'Follower' => array(
  'className' => 'User',
  'joinTable' => 'users_users',
  'foreignKey' => 'user_id',
  'associationForeignKey' => 'follower_id',
  'unique' => 'keepExisting',
) 
);

В UsersController.php

public function follow() {
/*need help here*/
}

В Users\index.ctp

<?php if ($current_user['id'] != $user['User']['id']) echo $this->Html->link('Follow', array('action' => 'follow', $user['User']['id'])); ?>

1 ответ

Решение

Лично я не считаю, что hasAndBelongsToMany хорошо подходит для подобных ситуаций. Это хорошо подходит для случаев, когда вы хотите отобразить список флажков или список выбора и позволить пользователю выбирать / управлять всеми своими действиями (или какими бы то ни было отношениями) в одной форме.

Это может быть просто моим личным предпочтением, но в таких ситуациях, как ваша, когда вы добавляете / удаляете отдельные ссылки, не беспокоясь о каких-либо других ссылках, связанных с этим пользователем, я предпочитаю просто создавать отдельные "Отношения" (или с аналогичным названием) Модель / Контроллер, и рассматривайте записи как самостоятельные вещи, в отличие от просто ссылок hasAndBelongsToMany, которые являются своего рода "автоматическими" управляемыми.

Вот как я это сделаю:

Назовите свою таблицу users_users "отношения". И назовите столбцы "follow_by_id" и "follow_id" (или аналогичные), чтобы избежать двусмысленности относительно того, какой пользователь является последователем / подписчиком (если это было слово!).

В вашей пользовательской модели вы будете иметь следующие отношения:

var $hasMany = array(
    'Followers' => array(
        'className' => 'Relationship',
        'foreignKey' => 'following_id',
        'dependent'=> true
    ),
    'FollowingUsers' => array(
        'className' => 'Relationship',
        'foreignKey' => 'followed_by_id',
        'dependent'=> true
    ),
);

Тогда у вас будет модель отношений, которая будет выглядеть примерно так (отношения $ ownTo являются важной частью):

<?php
class Relationship extends AppModel {
    var $name = 'Relationship';

    var $validate = array(
        'followed_by_id' => array(
            'numeric' => array(
                'rule' => array('numeric'),
            ),
        ),
        'following_id' => array(
            'numeric' => array(
                'rule' => array('numeric'),
            ),
        ),
    );

    var $belongsTo = array(
        'FollowedBy' => array(
            'className' => 'User',
            'foreignKey' => 'followed_by_id'
        ),
        'Following' => array(
            'className' => 'User',
            'foreignKey' => 'following_id'
        )
    );
}
?>

И тогда в вашем контроллере Relationships у вас будет что-то вроде этого:

function add($following_id = null) {
    $this->Relationship->create();
    $this->Relationship->set('followed_by_id',$this->Auth->User('id'));
    $this->Relationship->set('following_id',$following_id);
    if ($this->Relationship->save($this->data)) {
        // all good
    } else {
        // You could throw an error here if you want
        $this->Session->setFlash(__('Error. Please, try again.', true));
    }
    $this->redirect($this->referer());
}

Затем, чтобы добавить отношения, вы, очевидно, просто вызываете метод add вашего контроллера отношений.

ПРИМЕЧАНИЕ. В идеале, поскольку добавление отношения изменяет базу данных, в идеале это не следует делать с помощью запроса GET, доступ к которому осуществляется по обычному URL-адресу. Это должно быть сделано путем отправки формы через POST. Я знаю, что это кажется излишним, когда так просто сделать это через обычную ссылку с GET. Я не удосужился использовать формы /POST в этом примере - но если вы хотите придерживаться лучших практик, это то, что вы должны сделать. См. Это для получения дополнительной информации: https://softwareengineering.stackexchange.com/questions/188860/why-shouldnt-a-get-request-change-data-on-the-server

Другие вопросы по тегам