Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

laravel eloquent trouble matching multi-word table name

I love Eloquent so much when it's working! But this time I'm adding a table with a two-word name, and I have something wrong that I just don't see yet...

I already have a Person object/people table, with other entities having a one-to-many relationship working already. Now I'm adding the concept of audio files that can feature multiple people. I've added two tables for this:

  • audio_files (with auto id, filename, summary, timestamps)
  • audio_file_person (with auto id, audio_file_id and person_id)

Then I have AudioFile.php:

class AudioFile extends Model
{
    protected $fillable = [
        'filename', 'summary', 'recording_date'
    ];

    public function people()
    {
        return $this->belongsToMany('App\Person'); 
    }

    public function getPersonListAttribute()
    {
        return $this->people->lists('id')->all();
    }

}

And I've updated Person.php with this:

public function audio_files()
{
    return $this->belongsToMany('App\AudioFile')->withTimestamps();
}

public function getAudioFileListAttribute()
{
    return $this->audio_files->lists('id')->all();
}

Using the same pattern I've used for other records that people are associated with, in the person's view I'm checking to see if there are any audio files to show:

@unless ($subject->audio_files->isEmpty())
    <div>
        <h4>Audio links: </h4>
        @foreach($subject->audio_files as $audio)
            @include ('audio.partials.audio_link', ['audio' => $audio])
        @endforeach
        <br/>
    </div>
@endunless

However, this seems to be empty for people where I do have audio_file_person records for them.

Any suggestions on what I might be doing wrong or where else I should be checking? Thanks in advance for your help!

like image 780
Diane Kaplan Avatar asked Oct 29 '22 14:10

Diane Kaplan


1 Answers

Try indicating the pivot table in the belongsToMany relationship.

In your Person model:

public function audio_files()
{
    return $this->belongsToMany(AudioFile::class, 'audio_file_person', 'person_id', 'audio_file_id');
}

In your AudioFile model:

public function people()
{
    return $this->belongsToMany(Person::class, 'audio_file_person', 'audio_file_id', 'person_id');
}

For the audio_file_person table, I usually don't include an incremented id on a pivot table, but it shouldn't really pose a problem.

Update 1:

In the view:

@foreach($people as $person)
    {{$person->name}}: <br>
    @unless ($person->audio_files->isEmpty())
      <ul>
      @foreach($person->audio_files as $audio_file)
        <li>{{$audio_file->filename}}</li>
      @endforeach
    </ul>
    @endunless
@endforeach

Update 2:

In your project root:

> php artisan tinker
> use App\Person (or namespace of your Person model)
> $person = Person::find(1) (an id that you've set up in the pivot table)
> $person->audio_files

like image 95
yan_n Avatar answered Nov 09 '22 12:11

yan_n