how to make join query between three tables in laravel - laravel

I want to build a query in laravel between three tables (regions, countries, packages) such that table are related together.
regions table contains (id, name, description)
countries table contains (id, region_id, name, description)
packages table contains (id, county_id, pkg_title, pkg_description, price)
I want to select all packages where region_id=1
how can I make query for this situation in laravel query builder. please help me about this question

Set your models as follows.
class Region extends Model
{
}
class Country extends Model
{
public function region()
{
return $this->belongsTo(Region::class);
}
}
class Package extends Model
{
public function country()
{
return $this->belongsTo(Country::class);
}
}
And state following query inside your method.
$region_id = 1;
$PackageWithRegions = Package::with([
'country' => function ($county) use ($region_id) {
return $county->with([
'region' => function ($region) use ($region_id) {
return $region->where('id', $region_id);
}
]);
}
])->get();
// $PackageWithRegions is a collection of packeges with regions where regiion_id = 1
More on eloquent relationships

You can use Eloquent model relationship to prform this, like below
In region controller file
$region = Region::where(['id'=>1])->with(['country'])->get(); ///fetch region with country calls relation declared in region model
In Region.php model
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Region extends Model {
protected $table = 'regions';
public function country(){
return $this->hasOne('App\Models\Country','region_id')->with(['packages']); ///this will fetch country with all pacckages on matching region_id, join of package with country is declared in country model.
}
}
In Country.php model
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Country extends Model {
protected $table = 'countries';
public function packages(){
return $this->hasMany('App\Models\Package','county_id'); //join of country with packages on county_id
}
}
In Package.php model
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Package extends Model {
protected $table = 'packages';
}

You can see in Laravel doc (https://laravel.com/docs/4.2/eloquent) in section Has Many Through that if you have a model like:
countries
id - integer
name - string
users
id - integer
country_id - integer
name - string
posts
id - integer
user_id - integer
title - string
Then you can access to last relation in this way:
class Country extends Eloquent {
public function posts()
{
return $this->hasManyThrough('Post', 'User');
}
}
Or using customs relations IDs:
class Country extends Eloquent {
public function posts()
{
return $this->hasManyThrough('Post', 'User', 'country_id', 'user_id');
}
}
So, you can access to the posts of a country:
$posts = Country::get(2)->posts;
// with where:
$posts = Country::where('name', '=', 'USA')->get()->posts;

Related

Cannot establish relationship between two tables in Laravel

I want to create a relation between lising and attribute table in laravel for that i have used following code to establish relationship between them but the data in my view is not coming from both the tables. I'm getting following error:
Call to undefined relationship [adListAttributes] on model
[App\Models\AdListing].
Here listing can have as many attribute associated with and attributes
can be associated to many listings
ad_listings:
id
title
name
date
ad_list_attributes table :
id
listing_id
name
namespace App\Models;
use Eloquent;
use Illuminate\Database\Eloquent\Model;
class AdListAttribute extends Model
{
protected $table = "ad_list_attributes";
public function Listings()
{
return $this->belongsToMany('AdListing', 'id', 'listing_id');
}
}
namespace App\Models;
use Eloquent;
use Illuminate\Database\Eloquent\Model;
class AdListing extends Model
{
protected $table = "ad_listings";
public function Attributes()
{
return $this->belongsToMany('AdListAttribute', 'listing_id', 'id');
}
}
Problem is that you are using belongsToMany in both the models.This will cause a problem.
In AdListAttribute model,
public function listing_information()
{
return $this->belongsTo('App\AdListing', 'id', 'listing_id');
}
In AdListing model,
public function adlisting_attributes()
{
return $this->hasMany('App\AdListAttribute', 'listing_id', 'id');
}
You can get the results using,
$response = AdListing::get();
if($response->adlisting_attributes)
{
foreach($response->adlisting_attributes as $attribute)
{
echo $attribute->name;
}
}
Problem is that ur not calling the relationship with the right name i assume
$listings = AdListing::with('Attributes')->get();
Update :
Try this :
use App\Models\AdListAttribute;
//
return $this->belongsToMany(AdListAttribute::class, 'listing_id', 'id');
Same for other model, then try

Design a specific situation in laravel ( many to many relationship)

I want to ask about a specific situation..
I have 3 models :
Store
Price
Product
I have to set a specific price for a store on a specific product..
for example :
if I have product A that costs 100$ , I want to set it as 50$ for store A , 80$ for Store B ...etc
what I did is I created many-many relationship between Store and Price
and I stored product_id in pivot table...
like below
Store.php
<?php
namespace App\Modules\Store\Models;
use App\Modules\Store\Models\Price;
class Store extends Model
{
public function prices()
{
return $this->belongsToMany(Price::class,'store_prices');
}
}
Price.php
<?php
namespace App\Modules\Store\Models;
use App\Modules\Store\Models\Store;
use Illuminate\Database\Eloquent\Model;
class Price extends Model
{
protected $fillable = ['price'];
public function stores()
{
return $this->belongsToMany(Store::class, 'store_prices');
}
}
StorePrice.php
<?php
namespace App\Modules\Store\Models;
use App\Modules\Product\Models\Product;
use App\Modules\Store\Models\Price;
use App\Modules\Store\Models\Store;
use Illuminate\Database\Eloquent\Model;
class StorePrice extends Model
{
protected $fillable = ['store_id', 'price_id', 'product_id'];
protected $table = 'store_prices';
public function store()
{
return $this->belongsTo(Store::class, 'store_id');
}
public function price()
{
return $this->belongsTo(Price::class, 'price_id');
}
public function product()
{
return $this->belongsTo(Product::class, 'product_id');
}
}
is this logically true ?
if it is , how can I group a price by product and show the related stores ?
otherwise I hope u can give maybe better propositions
Thanks in advance
You don't need StorePrice Model. You just modify one of two models and add withPivot('product_id') like this
return $this->belongsToMany(Store::class, 'store_prices')->witPivot('product_id');
Regard to grouping, you can make if as a normal query which joins three tables ( store, pice and pivot) then group results based on product_id

Laravel | oneToMany with two foreign keys

I have two tables, invoice_header and invoice_detail
Both tables have loc_id and invo_no as reference keys between them.
How can I link them inside the model, can I use array for foreign keys?
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class InvoiceDetail extends Model
{
protected $table = 'invoice_detail';
public $timestamps = false;
protected $fillable = ['invo_no','loc_id','serial','item_id','qty','rtp','cost',
'discount','type'];
public function item(){
return $this->belongsTo('App\InvoiceHeader', ['loc_id', 'invo_no']);
}
}
https://laravel.com/docs/5.5/eloquent-relationships#one-to-many
You will want a details model and and invoice header model and invoice model and inter connect them.follow the article or rename your model to invoice and make to functions
//details
public function invoice(){
return $this->belongsTo(Invoice::class);
}
//invoice model
public function details(){
return $this->hasMany(InvoiceDetails::class);
}
public function headers(){
return $this->hasMany(InvoiceHeaders::class);
}
//headers model
public function invoice(){
return $this->belongsTo(Invoice::class);
}
//then you can get details and headers through
$invoice = Invoice::find(1);
$details = $invoice->details;
$headers = $invoice->headers;

Issue in laravel 5.3 relationship?

I want to search in contacts table and in communication links table according to name or mobile no. where my mobile is in communication_links table in 'value' and fname and lname is in contacts table. but there is a relation in communication link and in resource_status by using rest_id. and again resource_status is connected with resource type.
This is my raw sql query
SELECT contacts.fname, contacts.lname, communication_links.value FROM contacts ,communication_links,resource_status
where
(contacts.id = communication_links.cont_id)
AND
(communication_links.rest_id = resource_status.id)
AND
resource_type.status LIKE '{mobile}%'
AND
(communication_links.value LIKE '{$search_string}%' OR
contacts.fname LIKE '{$search_string}% OR contacts.lname LIKE '{$search_string}% )
I have following table structure
contacts
id
fname
lname
dob
communication_links
id
rest_id
cont_id
value
resource_type
id
type
resource_status
id
Status
rety_id
And I created following models to maintain the relationship
Contact.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Contact extends Model
{
protected $connection = 'mysql_freesubs';
public $timestamps = false;
public function communicationLinks()
{
return $this->hasMany(Communication_link::class, 'cont_id');
}
}
Communication_link.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Communication_link extends Model
{
protected $connection = 'mysql_freesubs';
public $timestamps = false;
public function resource()
{
return $this->belongsTo(Resource_status::class, 'rest_id');
}
public function contact()
{
return $this->belongsTo(Contact::class, 'cont_id');
}
}
Resource_status.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Resource_status extends Model
{
protected $connection = 'mysql_freesubs';
protected $table = 'resource_status';
}
Resource_type.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Resource_type extends Model
{
protected $connection = 'mysql_freesubs';
public $timestamps = false;
public function resourceStatuses()
{
return $this->hasMany(Resource_status::class, 'rety_id');
}
}
I tried to write same query as i have given above but i haven't got a desire result:
$parent_contact = \App\Contact::with('communicationLinks.resource')
->whereHas('communicationLinks.resource', function ($query) {
$query->where('status', 'LIKE', "{mobile}%");
})
->whereHas('communicationLinks.contact',function ($query) use($request) {
$query->where('communicationLinks.value','LIKE',"{$request->search_string}%")
->orWhere('fname','LIKE',"{$request->search_string}%")
->orWhere('lname','LIKE',"{$request->search_string}%");
})
->get();
$query = DB::table("contacts as a")
->select(array("a.fname", "b.lname", "b.value"))
->join("communication_links AS b", "a.id", "=", "b.cont_id")
->join("resource_type AS c", "b.rest_id", "=", "c.id")
->where("a.status", "like", $mobile."%")
->where("b.value", "like", $search_string."%")
->orWhere("a.fname", "like", $search_string."%")
->orWhere("a.lname", "like", $search_string."%")
->get();
That should do the job for you.
You can just iterate through it to get your values as desired

Laravel Eloquent Query Builder (Using query existence, using whereHas)

Tables
PROFILE
id address type approved fky_profile_vendor_id
VENDOR
id name
PRODUCT
id name price instock fky_prod_vendor_id
Relationship
PROFILE <-(one-to-one)-> VENDOR <- (one-to-many) -> PRODUCT
Query
Eloquent query to get all the products those are in stock
PRODUCT::where('instock','>',0)->get();
How can I get all the products in stock of a approved vendor?
Thanks
K
App\Profile
use Illuminate\Database\Eloquent\Model;
class Profile extends Model {
public function scopeApproved($query)
{
return $query->where('approved', 'y');
}
public function vendor()
{
return $this->belongsTo('App\\Vendor');
}
}
--
App\Vendor
use Illuminate\Database\Eloquent\Model;
class Vendor extends Model {
public function profile()
{
return $this->hasOne('App\\Profile');
}
public function products()
{
return $this->hasMany('App\\Product');
}
}
--
App\Product
use Illuminate\Database\Eloquent\Model;
class Product extends Model {
public function vendor()
{
return $this->belongsTo('App\\Vendor');
}
}
How to use:
$vendors = Vendor::whereHas('profile', function ($q) { $q->approved(); })->with('products')->get();
$products = $vendors->map(function ($vendor)
{
return $vendor->products;
});
This will return a Collection of Productss of Vendors with approved Profile.

Resources