delete with eager load in laravel - php

I'm trying to delete a collection but I want to delete the NFTs related to a collection as well. How do I do this?
‍‍This is my Nft model Nft.php
class Nft extends Model
{
use HasFactory,SoftDeletes;
public function collection()
{
return $this->belongsTo(Collection::class);
}
}
This is my collection model Collection.php
class Collection extends Model
{
use HasFactory, SoftDeletes;
public function nfts()
{
return $this->hasMany(Nft::class);
}
}
This is my COntroller CollectionController.php
public function deleteCollection(int $id):RedirectResponse
{
Collection::with('nfts')->find($id)->delete();
return redirect('/collections');
}
But it did not work!!!
pleas help me!!!!!

At user model:
public function collection() {
return $this->belongsTo(Collection::class)->withTrashed(); }

Keep in mind that the observer events are not fired if you use mass delete for example. In the case Collection::with('nfts')->delete(); it might not work.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Collection extends Model
{
/**
* The "booted" method of the model.
*
* #return void
*/
protected static function booted()
{
static::deleting(function ($collection) {
$collection->nfts()->delete()
});
}
}

Related

Make PHPStan understand Laravel Eloquent Builder query()

I am having a hard time making larastan / phpstan understand that query() should be based on Company model and not Eloquent\Model. What am I missing?
<?php
namespace App\Repositories;
use App\Models\Company;
/**
* #extends AbstractBaseRepository<Company>
*/
class CompanyRepository extends AbstractBaseRepository
{
public function __construct()
{
parent::__construct(new Company());
}
public function firstByDomain(string $domain): ?Company
{
return $this->query()
->where('domain', $domain)
->first();
}
}
<?php
namespace App\Repositories;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
/**
* #template TModel of Model
*/
abstract class AbstractBaseRepository
{
/** #var TModel */
protected $model;
/** #param TModel $model */
public function __construct(Model $model)
{
$this->model = $model;
}
public function query(): Builder
{
return $this->model->query();
}
}
And this is causing this error:
Method App\Repositories\CompanyRepository::firstByDomain() should return App\Models\Company|null but returns Illuminate\Database\Eloquent\Model|null.
It seems to me that this is caused by the query() method, returning an Eloquent Builder for Illuminate\Database\Eloquent\Model where I believe it should return an Eloquent Builder for App\Models\Company here.
You need to change the query method in AbstractBaseRepository to something like this:
/** #return Builder<TModel> */
public function query(): Builder
{
return $this->model->query();
}
because Builder class is also generic. Also PHPStan does not check the function/method bodies. So your return type needs to be accurate.

To carry out CRUD operations for multiple tables in a single view

I'm on Laravel 8 with Livewire, currently have 3 models, Category, SubCategory and MenuItem for 3 tables. All the above models have separate livewire controllers and have the code for the CRUD operations respectively. I have separate views and routes to edit the above tables and they all have a eloquent relationship between each other. Now what I need to do here to is, I need to display all the three tables in a single view to carry out the CRUD operations.
I tried to achieve this by using the sub-view function, to pass the view and make the variables available to the specific view, but it didn't work out and I think it isn't the way to do it, was just trying to figure a workaround. I'm mentioning my models down below for referencing. Please help me with this. Thanks a lot for your time!
App\Models\Category
class Category extends Model
{
use HasFactory;
protected $table = "categories";
protected $fillable = ['sub_category_name'];
public function SubCategories() {
return $this->hasMany(SubCategory::class, 'category_id');
}
public function MenuItems() {
return $this->hasManyThrough(
'MenuItem::class',
'SubCategory::class',
'sub_category_id',
'category_id'
);
}
}
App\Models\SubCategory
class SubCategory extends Model
{
use HasFactory;
protected $table = "sub_categories";
protected $fillable = ['category_id', 'sub_category_name'];
public function Categories() {
return $this->belongsTo(Category::class, 'category_id');
}
public function MenuItems() {
return $this->hasMany(MenuItem::class, 'sub_category_id');
}
}
App\Models\MenuItem
class MenuItem extends Model
{
use HasFactory;
protected $table = "menu_items";
protected $fillable = ['sub_category_id', 'item_name', 'item_description'];
public function SubCategories() {
return $this->belongsTo(SubCategory::class, 'sub_category_id');
}
}
This is what I tried to achieve the said result. As I needed to include the view with the sub category table to the menu items table view. I made the variables available to that specific view.
Resources\Views\Livewire\Menu-Item
<div>
#include('livewire.sub-category')
</div>
App\Providers\AppServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\View;
use App\Models\SubCategory;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
View::composer('livewire.menu-item', function ($view) {
$view::with('sub_category_name', SubCategory::orderBy('sub_category_name')->get());
});
}
}
I managed to solve the above problem, using livewire's component feature. Created 3 separate component for 3 separate tables, and finally used all the three components in the master-menu.blade.php file. Working with livewire and laravel is a treat.

Laravel Eloquent filter not found

I am trying to create a filter in Laravel.
I want to filter on the database field transmission but it is not working.
Here is my Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Occasion extends Model
{
protected $table = 'hexon_occasions';
public $primaryKey = 'id';
public $timestamps = true;
}
My Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use EloquentBuilder;
use App\Occasion;
class OccasionController extends Controller
{
public function index(Request $request)
{
$occasions = EloquentBuilder::to(
Occasion::class,
$request->all()
);
return $occasions->get();
}
public function show($slug)
{
$occasions = Occasion::where('slug', $slug)->first();
return view('occasions.show')->with('occasions', $occasions);
}
}
The filter:
namespace App\EloquentFilters\Occasion;
use Fouladgar\EloquentBuilder\Support\Foundation\Contracts\Filter;
use Illuminate\Database\Eloquent\Builder;
class TransmissionFilter implements Filter
{
/**
* Apply the age condition to the query.
*
* #param Builder $builder
* #param mixed $value
*
* #return Builder
*/
public function apply(Builder $builder, $value): Builder
{
return $builder->where('transmission', $value);
}
}
And the URL i am using is: https://www.laravel.bvdodev.nl/occasions?filter[transmission]=H
But I am getting the error: Not found the filter: FilterFilter
Does someone know what I am doing wrong?
Thanks for your time!

Trying to get the username using MODELS but getting this error: Trying to get property of non-object

ERROR: ErrorException in 814a6fb85b2cceb262c3a8191c08e42742940fc7.php line 223: Trying to get property of non-object (View: /var/www/html/m/TS/resources/views/d/show-details.blade.php)
Actually I am trying to get the username who has stored the result in the database i.e. TN has got user_id as a foreign key in the table so I need to get the username from that user_id using models but I am getting this problemTrying to get property of non-objectwhen I try to get theusername` associated with the id. I dont know where I am doing it wrong.
THE ERROR I AM GETTING IS HERE value="{{$tn->users->username}}" WHICH SHOWS IN THE CACHED FILE.
I have given my code below too to look.
Thank you in advance
Controller
public function details($id) {
$d= $this->detail->showDetails($id);
$tn= TN::find($id);
// calling functions from Model
$n = $d->tN;
$o = $d->tO;
return view('details.show-details', compact('d','o', 'n', 'tn'));
}
View
foreach($n as $n)
<input style="font-size:10px;font-weight: bold; color:black; background:#59d864;" value="{{$tn->users->username}}" readonly>
Models
User Model
<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\TN;
use App\TO;
use App\UserType;
class User extends Authenticatable
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'username', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function tN() {
return $this->hasMany(TN::class);
}
public function tO() {
return $this->hasMany(TO::class);
}
public function userType() {
return $this->belongsTo(UserType::class);
}
}
TO Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\D;
use App\TT;
use App\User;
class TO extends Model
{
protected $fillable = ['o', 'date'];
public function d() {
return $this->belongsTo(D::class);
}
public function tOType() {
return $this->belongsTo(TOType::class);
}
public function users() {
return $this->belongsTo(User::class);
}
}
TN Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Debtor;
use App\TracingType;
use App\User;
class TN extends Model
{
protected $fillable = ['r', 'date'];
public function d() {
return $this->belongsTo(D::class);
}
public function tType() {
return $this->belongsTo(TType::class);
}
public function users() {
return $this->belongsTo(User::class);
}
}
Hello I have sorted this problem but forgot to post it in here the problem was here
public function users() {
return $this->belongsTo(User::class);
}
This should be public function user() rather than users. Because it belongsTo to User class, it should be singular not plural and for hasMany we use plurals. Thank you for your help though ... :)

Laravel-Global scope trait not being hit

I can't seem to find the problem here. I'm using a trait to attach a global scope to all Eloquent queries on a model. Here is my model
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Club\traits\restrictToClubTrait;
class Product extends Model
{
public function category()
{
return $this->belongsTo('App\ProductCategory', 'product_category_id', 'id');
}
public function producer()
{
return $this->belongsTo('App\Producer', 'producer_id');
}
}
And here is the trait
<?php namespace App\Club\traits;
trait restrictToClubTrait
{
/**
* Boot the soft deleting trait for a model.
*
* #return void
*/
public static function bootRestrictToClubTrait()
{
dd('p');
static::addGlobalScope(new RestrictToClubScope);
}
}
That dd never gets hit, so the function must not be getting hit, I've poured over the docs but I don't see where I've gone wrong.
Traits should be "included" inside the class body. For more info here
use App\Club\traits\restrictToClubTrait;
class Product extends Model {
use restrictToClubTrait;
}

Categories