Laravel принадлежит функции ToMany

Я использую Laravel для создания базового сайта со следующей функцией: пользователь может следить за определенными темами. У меня есть таблица ‘users’, таблица ‘themes’, а в качестве сводной таблицы у меня есть таблица ‘follow’.

users
----
user_id (primary)
user_first_name
etc..following
---------
follow_id
user_id (foreign)
topic_id (foreign)topics
------
topic_id (primary)
topic_name
etc...

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

У меня есть модель пользователя со следующей функцией:

public function follows() {
return $this->belongsToMany('Topic', 'following', 'user_id', 'user_id');
}

Тем не менее, я не слишком уверен, куда идти отсюда (или это правильно!)

Был бы очень благодарен за любую помощь.

1

Решение

Прежде всего, вы допустили ошибку в своем следующем методе.
У вас одинаковое имя переменной с локальным и внешним идентификатором ‘user_id’.

Затем,
Вы уже добавили тему для пользователя?
Если да, было бы здорово, если бы вы сделали то же самое, что и в вашей модели User на модели Topic.

public function followedBy()
{
return $this->belongsToMany('User', 'following', 'topic_id', 'user_'id');
}

Отсюда вы можете добавить следующую тему для пользователей, выполнив

$user->following()->attach($topic_id);

Или же

$user->following()->attach([$first_topic, $second, $third, ...]);

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

Чтобы получить всю информацию, вы можете просто сделать следующее:

foreach ($user->following as $topic) {};

/! \ Не добавляйте круглые скобки к следующим, в противном случае вы получите QueryBuilder вместо набора тем. /! \

Если вы хотите добавить больше фильтров (например, только активные темы)

foreach ($user->following()->active()->get() as $topic) {}

Обратите внимание, что здесь я добавил круглые скобки, которые необходимы, потому что я не хочу, чтобы темы, а QueryBuilder фильтровали результаты.
Вызовите метод -> get (), когда закончите фильтрацию.

(Предположим, у вас есть метод scopeActive () в вашей модели)
Посмотрите область Laravel, чтобы сделать это: http://laravel.com/docs/eloquent#query-scopes

Вы можете сделать противоположное на стороне темы, выполнив:

foreach ($topic->followedBy as $user) {}

PS: простите за мой английский, если вы что-то не так поняли. Не мой родной язык.

3

Другие решения

Вы поддерживаете следующую функцию в пользовательской модели

public function follows() {
return $this->belongsToMany('Topic', 'following');
}

и используйте оператор ниже, чтобы получить все темы любого пользователя

$topics = User::find(1)->follows;

Где 1 — идентификатор пользователя для конкретного пользователя.

2

1 В вашей настройке вы используете первичные ключи не по умолчанию (topic_id / user_id / follow_id вместо id) поэтому обязательно установите:

protected $primaryKey = 'topic_id';

на каждой из ваших моделей соответственно.

2 Я бы предложил переименовать отношение — follows неоднозначно, если у вас там буквально 3 модели.

3 Ваше отношение к вашей текущей настройке, как уже предложено @ChainList:

public function follows()
{
return $this->belongsToMany('Topic', 'following', 'user_id', 'topic_id');
}

4 Чтобы проверить, следует ли пользователь уже следовать данной теме, сделайте это:

// I Assume logged in user
$user = Auth::user();
$topics = Topic::all();

// somewhere in your view
@foreach ($topics as $topic)
{{ $topic->name }}
@if ($user->follows->contains($topic->id))
Already following this topic
@else
Follow this topic (put a link here or whatever)
@endif
@endforeach

При этом вы запускаете только один запрос на темы пользователя, когда вы звоните $user->follows в первый раз.


Мое предложение будет:

// leave id as primary key, it will make your life easier

// rename relation to
public function topics()
{
// rename table name to something meaningful
return $this->belongsToMany('Topic', 'topic_user'); // laravel convention

// or if you like topics_followers
}
1

Почти там follows() отношения должны быть такими:

public function follows() {
return $this->belongsToMany('Topic', 'following', 'user_id', 'topic_id');
}

Затем вы сможете получить темы, связанные с текущим пользователем, выполнив следующее:

$topicsUserIsFollowing = Auth::user()->follows;

Чтобы начать следовать теме, вы можете сделать это (при условии, что у вас есть идентификатор темы):

Auth::user()->follows()->attach($topic_id);

редактировать
Если вы хотите увидеть, следует ли кто-то за темой, то в вашей модели Темы поместите такую ​​функцию:

public function isFollowedBy($user)
{
return $user->follows->contains($this->topic_id);
}

Итак, вы можете сделать что-то вроде этого:

$currentUser = Auth::user();

$topics = Topics::all();

foreach($topics as $topic) {
echo $topic->topic_name;
if( $topic->isFollowedBy($currentUser) ){
echo ' - [Already following this topic]';
}  else {
echo ' - [Follow this topic]';
}
}

Вы хотели бы поставить цикл в вашем представлении, это просто для иллюстрации

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector