I am beginner in Laravel. I have small problem with my code
In my system I have cabinets and boards from which it is made. I’m doing a cupboard builder. Each cabinet has specific plates assigned to it. Each cabinet may have different plates.
In this moment I have:
class Product extends Model { use ScopeActiveTrait; use Slugable; public function setNameAttribute($value) { $this->attributes['name'] = $value; $this->attributes['slug'] = $this->makeSlug($value); } protected $fillable = ['mark_popular', 'mark_new', 'delivery_time', 'product_type', 'name', 'title', 'description', 'keywords', 'content', 'vat_id', 'main_category_id', 'enable', 'slug', 'small_description']; protected $guarded = ['id']; public $timestamps = false; public function vat() { return $this->belongsTo('AppModelsVat', 'vat_id'); } public function category() { return $this->belongsTo('AppModelsCategory', 'main_category_id'); } public function selectedCategory() { return $this->hasMany('AppModelsSelectedProductCategory', 'product_id', 'id'); } public function related() { return $this->hasMany('AppModelsRelatedProduct', 'product_id', 'id'); } public function features() { return $this->hasMany('AppModelsSelectedProductFeature'); } public function frontImage() { return $this->hasMany('AppModelsUploadImage', 'file_id', 'id')->orderBy('order', 'ASC')->where('file_type', 'products'); } public function selectedPlates() { return $this->hasMany('AppModelsSelectedPlates', 'product_id', 'id'); } } class Plate extends Model { use ScopeActiveTrait; protected $fillable = ['name', 'enable', 'price', 'vat_id', 'type', 'description']; protected $guarded = ['id']; public $timestamps = false; public function frontImage() { return $this->hasMany('AppModelsUploadImage', 'file_id', 'id')->orderBy('order', 'ASC')->where('file_type', 'plates'); } public function vat() { return $this->belongsTo('AppModelsVat', 'vat_id'); } } class SelectedPlates extends Model { use ScopeActiveTrait; protected $guarded = ['id']; protected $fillable = ['plate_id', 'status', 'maxvalue', 'minvalue', 'product_id']; public function plate() { return $this->belongsTo('AppModelsPlate', 'vat_id'); } }
SelectedPlates – assigned to a product / plate cabinet
Plate – plates
Product – cabinets
I need a searchable display of all boards assigned to a given product / cabinet
I make this function:
public function getPlates(string $query, int $type, int $productId) { Product::active()->with(['vat', 'frontImage', 'selectedPlates'])->where(function ($q) use ($query, $type){ if ($query != "") { $q->where('name', 'LIKE', '%' . $query . '%'); $q->orWhere('description', 'LIKE', '%' . $query . '%'); } })->orderBy('name', 'asc')->get() }
this code return me 2 plates:
IlluminateDatabaseEloquentCollection {#1669 ▼ #items: array:1 [▼ 0 => AppModelsProduct {#1605 ▼ #fillable: array:14 [▶] #guarded: array:1 [▶] +timestamps: false #connection: "mysql" #table: "products" #primaryKey: "id" #keyType: "int" +incrementing: true #with: [] #withCount: [] #perPage: 15 +exists: true +wasRecentlyCreated: false #attributes: array:16 [▶] #original: array:16 [▶] #changes: [] #casts: [] #classCastCache: [] #dates: [] #dateFormat: null #appends: [] #dispatchesEvents: [] #observables: [] #relations: array:3 [▼ "vat" => AppModelsVat {#1640 ▶} "frontImage" => IlluminateDatabaseEloquentCollection {#1606 ▶} "selectedPlates" => IlluminateDatabaseEloquentCollection {#1642 ▼ #items: array:2 [▼ 0 => AppModelsSelectedPlates {#1702 ▶} 1 => AppModelsSelectedPlates {#1703 ▶} ] } ] #touches: [] #hidden: [] #visible: [] } ] }
Now I need search in this plates by:
if ($query != "") { $q->where('plates.name', 'LIKE', '%' . $query . '%'); $q->orWhere('plates.description', 'LIKE', '%' . $query . '%'); }
and filter by
->where(function ($q) use ($type) { $q->where('plates.type', $type); $q->orWhere('plates.type', 3); })
something like this:
public function getMaterials(string $query, int $type, int $produktId) { return Product->active()->with(['vat', 'frontImage'])->where(function ($q) use ($query, $type) { if ($query != "") { $q->where('plates.name', 'LIKE', '%' . $query . '%'); $q->orWhere('plates.description', 'LIKE', '%' . $query . '%'); } }) ->where(function ($q) use ($type) { $q->where('plates.type', $type); $q->orWhere('plates.type', 3); }) ->orderBy('name', 'asc')->get(); }
The above code doesn’t work. Does not search / filter. how can I make it?
Advertisement
Answer
You need to change few lines of code in order to this work. First add relation for plates
and then, for example:
public function getMaterials(string $query, int $type, int $produktId) { return Product->active()->with(['selectedPlates', 'selectedPlates.plate']) ->whereHas('selectedPlates', function ($q) use ($query, $type) { if (!empty($query)) { $q->where('name', 'LIKE', '%' . $query . '%'); $q->orWhere('description', 'LIKE', '%' . $query . '%'); } $q->whereHas('plate', function($q) use ($type) { $q->where('type', $type ?: 3); } }) ->orderBy('name', 'asc')->get(); }
Learn more of whereHas
on https://stackoverflow.com/a/30232227/3740460