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
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
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
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;
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
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.