简体   繁体   中英

Displaying a checkbox only for the shows(in the tvshow table) that don't match the entries for a given user id in the watchedtvshow table - Laravel

This is what I want to do: Display a checkbox for the tvshow field entry(from the tvshow table) only if that field entry doesn't match the entries for a given user id in the 'watchedtvshow' table

Table structure for 'tvshow':
id tvshow

Table structure for 'watchedtvshow'
id uid tvid(id of the tvshow)

Here is my controller method:

$tvshow = TVShow::with('watchedtvshow')->get();  
return View::make('browse',['tvshow' => $tvshow]);

My View:

@foreach($tvshow as $show)
   {{ $show->title }} {{ 'a checkbox' }}  
@endforeach

What I tried:
In my controller method:

$tvshow = TVShow::with('watchedtvshow')->get();

$uid = NULL;
if(Auth::check())
$uid = Auth::user()->id;

return View::make('browse',[
   'tvshow' => $tvshow,
   'uid' => $uid,
]);

In my view:

@foreach($tvshow as $show)
    {{ $show->title }}
    @foreach($show->watchedtvshow as $watchedtvshow)
        @if($watchedtvshow->uid == $uid)
            {{'don't show checkbox'}}
        @else
            {{'show checkbox'}}
        @endif
    @endforeach
@endforeach

The problem: The thing is the second foreach loop executes only for the times it finds a watched tv show, otherwise it doesn't. So it just won't show any checkboxes.

I'm not an experienced coder, haven't really encountered anything like this before, I've spent three whole days trying to solve this, using count, for loops and what not, but I can't. Does anybody know how to achieve this?

First off a quick pointer: you can get the logged-in user's ID with Auth::id() rather than having to set it to null, then check if they're logged in then get the id directly off the model.

As for your problem, you're quite right that using the code you have you won't be getting the full story. What you need to do is get a list of all TV shows (regardless of user having it) and additionally a list of all TV shows the user has seen. Now, you can do this many ways, but the best 'Laravel way' is to model the relationship between User and TVShow. Your code doesn't mention this so I won't assume you have already done it. Your database is, of course, already set up for this so all you need to do is create the relationship. In this case, the relationship you need is a belongsToMany (a user can 'have' (have watched) many shows, and a show can 'have' (have been watched by) many users:

// in User.php
public function shows()
{
    return $this->belongsToMany('TVShow', 'watchedtvshow', 'uid', 'tvid');
}

// in TVShow.php
public function users()
{
    return $this->belongsToMany('User', 'watchedtvshow', 'tvid', 'uid');
}

Once you have this you can get a list of all users that have watched a show with:

$show->users;

Or you can get a list of all shows a user has watched with:

$user->shows;

Now putting that all together you should use Laravel's collections to detect whether a given item if in both arrays:

// in the controller:
$shows = TVShow::all();

if (Auth::check()) {
    $watched = Auth::user()->shows;
} else {
    // just create an empty collection so we can assume a consistent API
    $watched = new \Illuminate\Support\Collection;
}

return View::make('browse', compact('shows', 'watched'));

// in browse.blade.php
@foreach($shows as $show)
    {{ $show->title }}

    @if ($watched->contains($show)
        <span class="glyphicon glyphicon-ok"></span>
    @else
        <span class="glyphicon glyphicon-remove"></span>
    @endif
@endforeach

Something like that?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM