skeith22 wrote a reply+100 XP
3h ago
Real Child Class Name is itself, so it's okay to reference it that way, although I think Eloquent's hasManyThrough doesn't know how to handle self referencing relationship.
Agent has many Agents through the Agent,
basically a self loop/self referencing relationship, but Eloquent doesn't have a method to handle Aliases for self referencing Model
skeith22 wrote a reply+100 XP
16h ago
The issue here is at the
on agentsaschild_agents.id=agents.parent_agent_idwhereagentsaschild_agents.id in (1)
where if you assign an alias name to the ChildAgent Class
protected $table = 'agents as child_agents';
it creates this query
SELECT
`agents`.*,
`agents` AS `child_agents.parent_agent_id`
FROM
`agents`
INNER JOIN `agents` AS `child_agents`
ON
`agents` AS `child_agents.id` = `agents`.`parent_agent_id`
WHERE
`agents` AS `child_agents.parent_agent_id` IN(1) AND `agents`.`deleted_at` IS NULL AND `agents` AS `child_agents.deleted_at` IS NULL)
INSTEAD of this correct query
SELECT
`agents`.*,
`child_agents`.`parent_agent_id`
FROM
`agents`
INNER JOIN `agents` AS `child_agents`
ON
`child_agents`.`id` = `agents`.`parent_agent_id`
WHERE
`child_agents`.`parent_agent_id` IN(1) AND `agents`.`deleted_at` IS NULL AND `child_agents`.`deleted_at` IS NULL;
skeith22 wrote a reply+100 XP
17h ago
Even having this is just 1064 error, which I think is close enough to solving this issue.
ChildAgent::class is just an Alias Model that extends the original Agent Class`
<?php
namespace App\Models;
class ChildAgent extends Agent
{
/**
* Child agents table.
*
* @var string
*/
protected $table = 'agents as child_agents';
}
public function lowerLevelTwoAgents(): HasManyThrough
{
return $this->hasManyThrough(
static::class,
ChildAgent::class,
'parent_agent_id',
'parent_agent_id',
'id',
'id'
);
}
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as `child_agents.id` = `agents`.`parent_agent_id` where `agents` as `child_agent' at line 1 (Connection: mysql, Host: 127.0.0.1, Port: 3306, Database: medifix, SQL: select `agents`.*, `agents` as `child_agents.id` from `agents` inner join `agents` as `child_agents` on `agents` as `child_agents.id` = `agents`.`parent_agent_id` where `agents` as `child_agents.id` in (1) and `agents`.`deleted_at` is null and `agents` as `child_agents.deleted_at` is null)
skeith22 wrote a reply+100 XP
17h ago
@glukinho apparently getThroughParent() is the one causing the relationship doesn't exist issue, doing other approach is just having MySQL 1064 or 1066 issues.
I've updated the Posts to reflect the actual code.
Having only this
public function lowerLevelTwoAgents(): HasManyThrough
{
return $this->hasManyThrough(
static::class,
static::class,
'parent_agent_id',
'parent_agent_id',
'id',
'id'
);
}
Results in
SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'agents'
skeith22 started a new conversation+100 XP
1d ago
Guys I have this model and I wanted to get the level 2 data, BUT this says relationship doesn't exist.
phpnamespace App\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasManyThrough;
class Agent extends Model { protected $table = 'agents';
/**
* The attributes that are mass assignable.
*
* @var list<string>
*/
protected $fillable = [
'parent_agent_id',
...
];
public function lowerLevelTwoAgents(): HasManyThrough
{
$relation = $this->hasManyThrough(
static::class,
static::class,
'parent_agent_id',
'parent_agent_id',
'id',
'id'
);
$relation->getThroughParent()->setTable('agents as child_agents');
return $relation;
}
}
skeith22 wrote a comment+100 XP
2w ago
@SarwarAhmed i follow the whole series hands on, my repo for this series is available if you need it
skeith22 wrote a comment+100 XP
2w ago
skeith22 liked a comment+100 XP
1mo ago
@radmax @andrewdv8 @halvarado77
Solution for Browser Test Issues with File Upload Forms
I experienced the same issue and found a solution based on a comment from the next video. The problem occurs when using enctype="multipart/form-data" on forms with Playwright browser tests.
The Fix
The solution is to dynamically set the enctype attribute using Alpine.js, only when a file is actually selected.
Step 1: Update the form's x-data
In resources/views/idea/index.blade.php, add a new hasImage property to track when a file is selected:
<form
x-data="{
status : 'pending',
newLink: '',
links: [],
newStep: '',
steps: [],
hasImage: false
}"
action="{{ route('idea.store') }}"
method="POST"
class="space-y-4"
x-bind:enctype="hasImage ? 'multipart/form-data' : false"
>
Step 2: Replace static enctype with dynamic binding
Replace the static enctype="multipart/form-data" attribute with:
x-bind:enctype="hasImage ? 'multipart/form-data' : false"
Step 3: Update the file input
Add an @change event to the file input to toggle hasImage when a file is selected:
<input
type="file"
name="image"
accept="image/*"
@change="hasImage = $event.target.files.length > 0"
/>
Why This Works
This approach prevents the form from using multipart/form-data encoding when no image is uploaded, which resolves conflicts with Playwright browser tests. The enctype is only set when an actual file is selected by the user.
Benefits
- ✅ Browser tests pass successfully without modifications to Composer packages
- ✅ File uploads still work correctly for end users
- ✅ No impact on form functionality
- ✅ Clean, maintainable solution using Alpine.js
Test Results
After implementing these changes:
PASS Tests\Browser\CreateIdeaTest
✓ it creates a new idea (1.95s)
Tests: 1 passed (9 assertions)
Duration: 2.42s
Hope this helps!
skeith22 liked a comment+100 XP
1mo ago
skeith22 wrote a comment+100 XP
1mo ago
@Go3shom we are facing the same issue : FAILED Tests\Browser\CreateIdeaTest > it creates a new idea Failed asserting that an array has the key 'title'.
at tests\Browser\CreateIdeaTest.php:21 17▕ ->press('Create') 18▕ ->assertPathIs('/ideas'); 19▕ 20▕ ➜ 21▕ expect($user->ideas()->first())->toMatchArray([ 22▕ 'title' => 'Idea Title Test', 23▕ 'status' => 'completed', 24▕ 'desription' => 'I want to test my modal if can create a new idea.', 25▕ 'links' => ['https://google.com', 'https://laracasts.com'],
skeith22 liked a comment+100 XP
1mo ago
arrow-back.blade.php
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="lucide lucide-arrow-left-icon lucide-arrow-left">
<path d="m12 19-7-7 7-7" />
<path d="M19 12H5" />
</svg>
skeith22 liked a comment+100 XP
1mo ago
external.blade.php
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
class="lucide lucide-external-link-icon lucide-external-link">
<path d="M15 3h6v6" />
<path d="M10 14 21 3" />
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
</svg>
skeith22 wrote a comment+100 XP
1mo ago
@Go3shom i think you should meant directly like this when rendering: {{ $statusCount['all'] }}, because if you do : {{ $statusCounts->count()}} it count all the rows status in your db which means count all the rows in db even the current user is not owned that idea or not the current auth.
skeith22 wrote a comment+100 XP
2mos ago
@jeffey - i think you can also use the Request object to extract authenticated user instance there like this one: public function store(IdeaRequest $request) {
$request->user()->ideas()->create([
'description' => $request->description,
]);
return redirect('/ideas');
}
this would be cleaner and clearer
skeith22 liked a comment+100 XP
2mos ago
And in the controller if we are using authorize method with one parameter, we are using gate:
Gate::authorize(parameter1);
// ex.
Gate::authorize(gateName);
If we are using authorize method with 2 parameters, we are using policies:
Gate::authorize(parameter1, parameter2);
// ex.
Gate::authorize(methodName, modelOrClassInstance);