Laravel Fetching one to Many Relationship - laravel

Hello I am learning laravel and I am having an issue retrieving data from my relations.
In my database there are Product and Groups filled with dummy data.
I defined my relationship like this in product model:
public function Group()
{
return $this->hasMany('App\Groups','product_id', 'id');
}
And in my group vice versa with :
public function Product()
{
return $this->belongsTo('App\Product','product_id', 'id');
}
The way I am referencing to my products table is :
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
Now I have column product_id in my database under groups, and it is linked to if from products id it seems.
The groups table contains of its auto incremented id and product_id foreign key column.
While products table has auto incremented id and name column.
The issue is here :
How do I return the products that are not null or have value (of products id) in groups table.
I tried something like this in my filter controller:
public function getProductsWithGroup()
{
$Products = Product::with('groups')->get();
return $Products ;
}
But that is giving me call to undefined relations.
I am not sure how to access belongsTo or hasMany methods and whether I need an extra group_id column in my products table.

You named the relationship wrong. It should be groups & define in lowercase as
public function groups()
{
return $this->hasMany('App\Groups','product_id', 'id');
}
And use ->has() to check existence
public function getProductsWithGroup()
{
$Products = Product::has('groups')->get();
return $Products ;
}
->with() is used to eager load and ->has() is used to check existence & filter.
To get the products don't have any groups,
$Products = Product::doesntHave('groups')->get();
To see other ways to use ->has() check, https://laravel.com/docs/5.7/eloquent-relationships#querying-relationship-existence

Related

Join tables in Laravel Eloquent method

How to write this code in eloquent method ?
$product = DB::table('products')
->join('purchase', 'products.id', '=', 'purchase.id')
->join('sales', 'purchase.id', '=', 'sales.id')
->select('sales.*', 'purchase.*','products.*')
->get();
Create model Product and add one to many relationship with Purchase in Product model.
public function purchases()
{
return $this->hasMany('App\Models\Purchase');
}
Create model Purchase and add one to many relationship with Sale in Purchase model.
public function sales()
{
return $this->hasMany('App\Models\Sale');
}
Create model Sale.
You can retrieve data using following statement.
$products = Product::with('purchases.sales')->get();
Note: I am assuming the relationship as one to many you can also declare as per your data, also you can define one to many inverse relationship, please refer to laravel docs https://laravel.com/docs/8.x/eloquent-relationships#one-to-many.
You will get purchases and sales data in different key so you can use below syntax to loop over it.
foreach ($products as $product) {
foreach ($product->purchases as $purchase) {
//Purchase data for current product
foreach($purchase->sales as $sale){
//Sale data for current purchase
}
}
}

Get only one column from relation

I have found this: Get Specific Columns Using “With()” Function in Laravel Eloquent
but nothing from there did not help.
I have users table, columns: id , name , supplier_id. Table suppliers with columns: id, name.
When I call relation from Model or use eager constraints, relation is empty. When I comment(remove) constraint select(['id']) - results are present, but with all users fields.
$query = Supplier::with(['test_staff_id_only' => function ($query) {
//$query->where('id',8); // works only for testing https://laravel.com/docs/6.x/eloquent-relationships#constraining-eager-loads
// option 1
$query->select(['id']); // not working , no results in // "test_staff_id_only": []
// option 2
//$query->raw('select id from users'); // results with all fields from users table
}])->first();
return $query;
In Supplier model:
public function test_staff_id_only(){
return $this->hasMany(User::class,'supplier_id','id')
//option 3 - if enabled, no results in this relation
->select(['id']);// also tried: ->selectRaw('users.id as uid from users') and ->select('users.id')
}
How can I select only id from users?
in you relation remove select(['id'])
public function test_staff_id_only(){
return $this->hasMany(User::class,'supplier_id','id');
}
now in your code:
$query = Supplier::with(['test_staff_id_only:id,supplier_id'])->first();
There's a pretty simple answer actually. Define your relationship as:
public function users(){
return $this->hasMany(User::class, 'supplier_id', 'id');
}
Now, if you call Supplier::with('users')->get(), you'll get a list of all suppliers with their users, which is close, but a bit bloated. To limit the columns returned in the relationship, use the : modifier:
$suppliersWithUserIds = Supplier::with('users:id')->get();
Now, you will have a list of Supplier models, and each $supplier->users value will only contain the ID.

Laravel Left join multiple tables and return the original table value

I'm having issues with joining three tables and getting the original table value back.
I have a parent table which is a store that needs to find the brand_id for the products within the store. I can't access the brand_id directly so I need to join, I have to join on to the stores product list then join that onto the product table which holds the brand_id.
$this_return = Store::with('address','setting')
->leftjoin('StoreProducts', function ($join){
$join->on('StoreProducts.store_id', '=', 'stores.id');
})->leftjoin('products', function ($join) {
$join->on('products.id','=','StoreProducts.product_id');
})
->where('products.brand_id', '=', $brandID)
->isActive()
->get();
This is returning a product value, But I wanted it to return all the stores the original table back if the products.brand_id was equal to the $brandID then return the current store and repeat for all stores.
Hope that makes sense
Any help would be great.
I think your relations goes like this:
Stores -> (n*n)StoreProducts -> Products -> (n*1)Brands
which StoreProducts is a joining table between Stores and Products. With this assumption, I would use something like this:
In the Store model,
public function products(){
return $this->belongsToMany(\App\Product::class, "store_products");
}
In the Products model,
public function stores(){
return $this->belongsToMany(\App\Store::class, "store_products");
}
In the StoreProducts model,
public function store(){
return $this->belongsTo(\App\Store::class);
}
public function product(){
return $this->belongsTo(\App\Product::class);
}
This way the relationship is created. Then you can use something like this:
$stores = \App\Store::whereHas("products", function($q) use ($brandId){
return $q->where("brand_id", $brandId);
});
This will give you the stores which the brand exists.

How to connect three tables in Laravel?

I have thee tables: Orders, Products, Products_images.
I need to get ll orders, for this I do:
$orders = Order::with("products")->where("user_id", Auth::guard('api')->user()->id)->orderBy('id')->get();
Where with("products") is function in model Order
public function products()
{
return $this->hasOne("App\Product", "id", "product_id");
}
So, I have connected two table. Also I need connect with table Products with table Products_images in this query.
How can I do this?
Add a product_images function to the Products Model
public function product_images() { return $this->hasMany("App\ProductImage");}
Modify the above line's App\ProductImage to reflect the model for your table. Then you can access all the product images records that belongs to your products by doing the following:
$orders = Order::with("products.product_images")->where("user_id", Auth::guard('api')->user()->id)->orderBy('id')->get();
Look under nested eager loading on this link : https://laravel.com/docs/5.3/eloquent-relationships#eager-loading

Laravel Get products from multiple taxonomies

I have 3 tables, products, taxonomies and product_taxonomy. The 3rd table is a pivot table that contains product_id and taxonomy_id, meaning that product and taxonomy are many to many relationship. Given a list of taxonomy ids, how can I get all the products that belong to these taxonomies? NOTE: I want to have the products result set being able to paginated or order by maybe it's price or something.
You need to create many-to-many relationship and that requires relationship methods like:
// Product Model
public function taxonomies()
{
return $this->belongsToMany('Taxonomy');
}
// Taxonomy Model
public function products()
{
return $this->belongsToMany('Product');
}
The query:
$listOfTaxonomyIds = [1,2,3];
$products = Product::whereHas('taxonomies', function($query) use ($listOfTaxonomyIds){
$query->whereIn('taxonomy_id', $listOfTaxonomyIds);
})->get();

Resources