F
Filament10mo ago
Wirkhof

How to force relation manager to use a specific table column?

I have a DB table notes as a relation manager (to store notes about various animals) and there is animal_id column (not a primary key, that is traditionally id as usual, just an arbitrary integer identifier). I have 3 models using one common table animals. First model is Animal (the original one) and additional two I created later: Dog and Cat. They all use the same table animals. Also corresponding resources AnimalResource, DogResource and CatResource. I have created relation manager for all three of them. First for AnimalResource and then for DogResource and CatResource. I ended up with this: App\Filament\Resources\AnimalResource\RelationManagers\NotesRelationManager.php for notes for AnimalResource. App\Filament\Resources\DogResource\RelationManagers\NotesRelationManager.php for notes for DogResource. App\Filament\Resources\CatResource\RelationManagers\NotesRelationManager.php for notes for CatResource. Showing lists of notes under the form of AnimalResource works. Showing the lists of notes under the form of DogResource and CatResource doesn't work. When I scroll down on the edit page of DogResource or CatResource I will get this error message:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'notes.dog_id' in 'where clause'
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'notes.dog_id' in 'where clause'
for dogs and:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'notes.cat_id' in 'where clause'
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'notes.cat_id' in 'where clause'
for cats. Filament should use notes.animal_id instead of notes.dog_id or notes.cat_id to get the results from the notes table based on the value in the animal_id column. How to force Filament to use animal instead of dog or cat for building the query for the relation manager? Is there any way to set the query id name to by used across the queries in relation manager? Currently it is grabing it automatically from the namespace or filename it seems.
Solution:
Look at the following documentation : https://laravel.com/docs/10.x/eloquent-relationships#one-to-many you need something like this : return $this->hasMany(Comment::class, 'foreign_key', 'animimal_id');...
Laravel - The PHP Framework For Web Artisans
Laravel is a PHP web application framework with expressive, elegant syntax. We’ve already laid the foundation — freeing you to create without sweating the small things.
Jump to solution
8 Replies
Wirkhof
WirkhofOP10mo ago
EDIT: Here is the query call that Laravel errors out:
SELECT
count(*) AS aggregate
FROM
`notes`
WHERE
`notes`.`dog_id` = 100
AND `notes`.`dog_id` IS NOT NULL
AND `notes`.`deleted_at` IS NULL
SELECT
count(*) AS aggregate
FROM
`notes`
WHERE
`notes`.`dog_id` = 100
AND `notes`.`dog_id` IS NOT NULL
AND `notes`.`deleted_at` IS NULL
Filament should use notes.animal_id instead of notes.dog_id or notes.cat_id to get the results from the notes table based on the value in the animal_id column. But it is instead trying to get value from dog_id , but such column doesn't exist. It's just the name of the model (Dog) and resource (DogResource), but the table and column is animal and animal_id. Any idea how can this be solved? Is this the problem? https://laravel.com/docs/10.x/eloquent#primary-keys or rather this https://laravel.com/docs/10.x/eloquent#retrieving-single-models It's probably not possible to use two resources with one model and not being stuck when using relation manager in both. Despite many people here told me that's the way to go 😭 Is it possible to tell Filament to use a specific column when using Relation Manager and not what he derives from the namespace?
Tieme
Tieme10mo ago
Share your relation model code please
Wirkhof
WirkhofOP10mo ago
Model or RelationManager file?
Tieme
Tieme10mo ago
model
Wirkhof
WirkhofOP10mo ago
ok a econd
<?php

namespace App\Models;

use Filament\Panel;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Dog extends Model
{
use HasFactory;
use SoftDeletes;

protected $table = 'animals';

public function notes(): HasMany
{
return $this->hasMany(Note::class);
}

}
<?php

namespace App\Models;

use Filament\Panel;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;

class Dog extends Model
{
use HasFactory;
use SoftDeletes;

protected $table = 'animals';

public function notes(): HasMany
{
return $this->hasMany(Note::class);
}

}
Tieme
Tieme10mo ago
and the notes?
Solution
Tieme
Tieme10mo ago
Look at the following documentation : https://laravel.com/docs/10.x/eloquent-relationships#one-to-many you need something like this : return $this->hasMany(Comment::class, 'foreign_key', 'animimal_id');
Laravel - The PHP Framework For Web Artisans
Laravel is a PHP web application framework with expressive, elegant syntax. We’ve already laid the foundation — freeing you to create without sweating the small things.
Wirkhof
WirkhofOP10mo ago
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;

class Note extends Model
{
use HasFactory;
use SoftDeletes;

public function animal(): BelongsTo
{
return $this->belongsTo(Animal::class);
}



}
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;

class Note extends Model
{
use HasFactory;
use SoftDeletes;

public function animal(): BelongsTo
{
return $this->belongsTo(Animal::class);
}



}
Yeah, it will probably be the lack of defining foreign key eithr for belongs to or one to many. Thanks for pointing me in the right direction, at least I hope so 😉 Yes, solved! hasMany in Dog.php (and Cat.php) model file should look like this:
public function notes(): HasMany
{
return $this->hasMany(Note::class, 'animal_id');
}
public function notes(): HasMany
{
return $this->hasMany(Note::class, 'animal_id');
}
the foreign key animal_id as a second paramter fixed it. without it it would use dog_id or cat_id.
Want results from more Discord servers?
Add your server