Laravel 6 - whereHasMorph Relationship Return Empty - php

I'm new to laravel Polymorphic Relationship. i have 2 table Supplier and Product and have Category to each table, so i'm decide to use Polymorphic Relationship. i want to query supplier-category but its return empty array.
// My Category Model
class Category extends Model
{
protected $fillable = ['categorizable_type', 'categorizable_id'];
public function categorizable()
{
return $this->morphTo();
}
}
// My Supplier Model
class Supplier extends Model
{
protected $fillable = ['name', 'email', 'phone'];
public function categories()
{
return $this->morphMany(\App\Category::class, 'categorizable');
}
}
// My Product Model
class Product extends Model
{
protected $fillable = ['product_code', 'product_name'];
public function categories()
{
return $this->morphMany(\App\Category::class, 'categorizable');
}
}
// And in SupplierController i want to query categorizable_type
public function index(Request $request)
{
// $product = Category::all();
$product = Category::whereHasMorph('categorizable', Supplier::class , function($query){
$query->where('categorizable_type', 'like', '%foo%');
})->get();
dd($product);
// return response()->json($product);
}
Thanks in advance...

Im make it working by change my code like below
$product = Category::whereHasMorph('categorizable', Supplier::class)->get();

Related

How to add model's relationed condition to Eloquent query in Laravel 6.x?

In my Laravel 6.x project I have Product model, ProductCategory and WarehouseProduct models.
In the Product I store the base information of my products. In ProductCategory model I store the category informations of products. In the WarehouseProduct I store the stock amount informations about products in warehouse. Of course I have many warehouses with many products.
My Product looks like this:
class Product extends Model
{
protected $fillable = [
'name',
'item_number',
// ...
];
public function categories() {
return $this->belongsToMany(ProductCategory::class, 'product_category_products',
'product_id', 'product_category_id');
}
}
The ProductCategory looks like this:
class ProductCategory extends Model
{
protected $fillable = [
'name',
'description',
// ...
];
public function products() {
return $this->belongsToMany(Product::class, 'product_category_products',
'product_category_id', 'product_id');
}
}
The WarehouseProduct looks like this:
class WarehouseProduct extends Model
{
protected $fillable = [
'product_id',
'warehouse_id',
'amount',
// ...
];
public function product() {
return $this->belongsTo(Product::class, 'product_id');
}
}
I have this query now:
$query = WarehouseProduct::select([
'product_id',
'warehouse_id',
DB::raw('SUM(free_amount)'),
DB::raw('SUM(booked_amount)'),
// ...
]);
if (isset($request->warehouse_id)) {
$query->where([['warehouse_id', '=', $request->warehouse_id]]);
}
if (isset($request->product_category_id)) {
// ???
}
How can I add a where condition to the query what said: products from this category?
You can query the Relationship Existence. As it is a relationship through another model (Product) you could reduce the query if you defined that Has Many Through relationship, but I think that this will be enough for this particular query.
$warehouse_id = $request->warehouse_id;
$product_category_id = $request->product_category_id;
$query = WarehouseProduct::select([
'product_id',
'warehouse_id',
DB::raw('SUM(free_amount)'),
DB::raw('SUM(booked_amount)'),
// ...
])
->when($warehouse_id, function ($query) use ($warehouse_id) {
$query->where('warehouse_id', $warehouse_id);
})
->when($product_category_id, function ($query) use ($product_category_id) {
$query->whereHas('product', function ($que) use ($product_category_id) {
$que->whereHas('categories', function ($q) use ($product_category_id) {
$q->where('id', $product_category_id);
})
})
});
$results = $query->get();
Note that I am using the when method for the conditional clauses, but you can continue with the ifs as you was doing.

How to access all data from pivot table laravel?

I am a beginner in Laravel and am stuck with sending the data from pivot table to view. I have two models one is "Supplier" and another is "Product" which I have created as follows:
Supplier.php
class Supplier extends Model
{
protected $keyType = 'string';
public $incrementing = false;
public function products()
{
return $this->belongsToMany(
'App\Product',
'inward_stock',
'supplier_id',
'product_id'
)->withPivot(
'product_dimension',
'quantity',
'expiry_date',
'type',
'QR_code',
'sales_price',
'arrival_date',
'occassion',
'discount_percentage',
'payment_date',
'cost',
'paid_status',
'sku'
)->withTimestamps();
}
}
Product.php
class Product extends Model
{
protected $keyType = 'string';
protected $primaryKey = 'product_id';
public $incrementing = false;
public function suppliers()
{
return $this->belongsToMany('App\Supplier');
}
}
Now I want to access all the data from the pivot table named as "inward_stock" from my controller and want to send it to the view named "inward-stock-list", I have created "inwardstockController" for that purpose and want to know how to send it to the view using that controller.
I think the most effective way is to create model for pivot table:
class InwardStock extends Model
{
protected $table = 'inward_stock';
public function supplier()
{
return $this->belongsTo('App\Supplier', 'supplier_id', 'supplier_id');
}
public function product()
{
return $this->belongsTo('App\Product', 'product_id', 'product_id');
}
}
inwardstockController:
$inwardStocks = InwartStock::with(['product', 'supplier'])->get();
View:
#foreach($inwardStocks as $inwardStock)
{{ $inwardStock->supplier->id }}
{{ $inwardStock->product->id }}
#endforeach

How to get only active element from many to many relationship with translation in laravel

I have a problem with a many to many relationship and the translations of the terms.
I have 4 tables:
products
- id, price, whatever
products_lang
- id, product_id, lang, product_name
accessori
- id, active
accessori_lang
- id, accessori_id, lang, accessori_name
I'm trying to assign accessories to products with an intermediate table named:
accessori_products
this is the model for Product:
class Product extends Model {
protected $table = 'products';
public function productsLang () {
return $this->hasMany('App\ProductLng', 'products_id')->where('lang','=',App::getLocale());
}
public function productsLangAll() {
return $this->hasMany('App\ProductLng', 'products_id');
}
public function accessori() {
return $this->belongsToMany('App\Accessori', 'accessori_products');
}
}
this is the model for productLng:
class ProductLng extends Model {
protected $table = 'products_lng';
public function products() {
return $this->belongsTo('App\Product', 'products_id', 'id');
}
}
Then I have the model for Accessori:
class Accessori extends Model {
protected $table = 'accessori';
public function accessoriLang() {
return $this->hasMany('App\AccessoriLng')->where('lang','=',App::getLocale());
}
public function accessoriLangAll() {
return $this->hasMany('App\AccessoriLng');
}
public function accessoriProducts() {
return $this->belongsToMany('App\Products', 'accessori_products', 'accessori_id', 'products_id');
}
}
And the model for AccessoriLng:
class accessoriLng extends Model {
protected $table = 'accessori_lng';
public function accessori() {
return $this->belongsTo('App\Accessori', 'accessori_id', 'id');
}
}
I get the results by this:
$products = Product::has('accessori')->with([
'productsLang ',
'accessori' => function ($accessori){
$accessori->with([
'accessoriLang'
]);
}
])->get();
return $products;
but I want to get only the active accessories something like where accessori.active = 1 but I really don't know where to put it. I've tried in different way but I'm stuck on it by 2 days.
IIRC you don't need a model for the intermediate table on your many to many relationships.
If you want to return Products where Accessori is active you can use whereHas on the Product model.
$prod = Product::whereHas('accessori', function($query) {
$query->where('active', 1);
})->get();
Where the $query param will be running on the Accessori model.
You can do the inverse as well with Accessori to Product.
$acessoris = Accessori::where('active', 1)->whereHas('accessoriProduct')->with(['accessoriLang', 'accessoriProducts.productsLang'])->get();

One to Many Relationship - Laravel & Mysql

In my application, Users can have many products. Now, i am trying to display the users phone number for a every displayed products.
In my products table, there is a column user_id for the respective users.
This is how my model looks like
User Model
public function products()
{
return $this->belongsTo('Models\Database\User','user_id');
}
Product Model
class Product extends BaseModel
{
protected $fillable = ['user_id','type', 'name', 'slug', 'sku', 'description',
'status', 'in_stock', 'track_stock', 'qty', 'is_taxable', 'page_title', 'page_description'];
// protected $guarded = ['id'];
public static function getCollection()
{
$model = new static;
$products = $model->all();
$productCollection = new ProductCollection();
$productCollection->setCollection($products);
return $productCollection;
}
public function users()
{
return $this->hasMany('\Models\Database\Product');
//->withTimestamps();
}
public function categories()
{
return $this->belongsToMany(Category::class);
}
public function reviews()
{
return $this->hasMany(Review::class);
}
public function prices()
{
return $this->hasMany(ProductPrice::class);
}
public function orders()
{
return $this->hasMany(Order::class);
}
public function users()
{
return $this->hasMany('Models\Database\Product');
}
And in my view, this is how i try to get the respective user's phone number
<p>{{$product->users->phone}}</p>
But i get an error like
SQLSTATE[42S22]: Column not found: 1054 Unknown column
'products.product_id' in 'where clause' (SQL: select * from products
where products.product_id = 1 and products.product_id is not
null)
You should do:
User Model
public function products()
{
return $this->hasMany('Models\Database\Product');
}
Product Model
public function user()
{
return $this->belongsTo('Models\Database\User');
}
In your blade:
{{ $product->user->phone }}
You have got your relationship models inverted,
change them:
In your User model:
public function products()
{
return $this->hasMany('Models\Database\Product');
}
In your Product model:
public function user()
{
return $this->belongsTo('Models\Database\User','user_id');
}
And then you could access the properties like:
<p>{{$product->user->phone}}</p>
Link to the Docs

Laravel Many to Many relationship gets partial results

I have Course and Category Models with many to many relationship between them. So I created CategoryCourse Model to decompose relationship. Here are my three models:
class CategoryCourse extends Model
{
private $foreignkeys = [
'$category_id','$course_id'
];
public function categories()
{
return $this->belongsToMany('App\Category');
}
public function courses()
{
return $this->belongsToMany('App\Course');
}
}
class Category extends Model
{
protected $title = ['title'];
public function categorycourse()
{
return $this->hasMany('App\CategoryCourse');
}
}
class Course extends Model
{
protected $fillable = [
'title', 'desc'
];
public function categorycourse()
{
return $this->hasMany('App\CategoryCourse');
}
}
In my controller I have method as follows:
public function getCoursesByCategory(Request $request, $id)
{
$id = Hashids::decode($id);
$categories = Category::findOrFail($id[0]);
$courses = $categories->categorycourse()->get();
return view('courses',compact('courses'));
}
I have three tables in database, they are categories, courses and category_courses. My view is displaying results from category_courses but not results from courses. I am learning laravel. Can any one please help? I want to display all courses that belong to a category, in my view.
Here is my view code:
#foreach($courses as $course)
{{$course->title}}
#endforeach
You have to change your code to:
class Category extends Model
{
protected $title = ['title'];
public function courses()
{
return $this->belongsToMany('App\Course', 'category_course', 'category_id', 'course_id');
}
}
The relationship should be in Category only.
And then you call:
$courses = $categories->courses;

Categories