How to get Complex relation in a Laravel using eloquent - php

I have below tables
Users
id
name
Companies
id
user_id
name
Product Categories
id
company_id
name
Products
id
product_category_id
name
Sales
id
product_id
price
quantity
total
Now i want to get all sales for specified user's products. I have tried with below query. But i cannot use where for this. It is not apply this filter. Also i want to filter it by few other fields like users.user_name, products.product_name ... etc
$sales = Sale::with(['product'=>function($q) use ($user_id) {
$q->with(['product_category' => function($q) use ($user_id) {
$q->with(['company'=> function($q) use ($user_id) {
$sUserName = Input::get('sUserName');
$q->with(['user'=> function($q) use ($sUserName,$user_id) {
$q->where('id', $user_id);
}]);
}]);
}]);
}]);
Is it possible to use Eloquent for these situations ? Or should i use join queries ? Please advice me. thanks

you can use laravel eloqunt like this.
$Sales = DB::table('Sales')
->join('Products', 'Sales.product_id', '=', 'Products.id')
->join('ProductCategories', 'ProductCategories.id', '=', 'Products.product_category_id')
->join('companies', 'ProductCategories.company_id', '=', 'companies.id')
->join('Users', 'companies.user_id', '=', 'Users.id')
->select('Sales.*')
->get();

After madalinivascu advise i could be able to resolve my problem as below. Now i can filter it by Ordered User, Product name & dates.
$sUserName = Input::get('sUserName');
$sProductName = Input::get('sProductName');
$sFrom = Input::get('sFrom');
$sTo = Input::get('sTo');
$user_id = \Auth::User()->id;
// Show sales only for his products
$sales = Sale::with('sold_to_user')
->whereHas('sold_to_user', function($q) use ($sUserName) {
if(!empty($sUserName)) $q->where('name','LIKE', "$sUserName%");
})->with('product')
->whereHas('product', function($q) use ($sProductName) {
if(!empty($sProductName)) $q->where('name','LIKE', "$sProductName%");
});
if(\Auth::User()->privilege!='administrator') $sales = $sales->where('user_id','=',$user_id);
$sales = $sales->orderBy('updated_at','desc')->paginate(100);

Related

If condition joined query in laravel

I have made a query in Laravel by joining 2 tables based on an IF condition.
I need to add a where query to filter data based on the material_id column from joined tables.
$transactions = DB::table('transactions')
->select('transactions.id', DB::raw("IF(transactions.is_sell = '1', advertisements.material_id, offerrequests.material_id) as material_id"))
->leftJoin('advertisements', function ($join) {
$join->on('advertisements.id', '=', 'transactions.post_id');
})
->leftJoin('offerrequests', function ($join) {
$join->on('offerrequests.id', '=', 'transactions.post_id');
});
I have tried the following and it is querying data with the requesting material_id from joined tables.
but also in the end i can see transaction values which are not similar to 'material_id' in the input.
I need to only get data which is exactly matches the same material id.
$transactions = $transactions->where(function ($query) use ($request) {
$query->where('advertisements.material_id', $request->material)
->orWhere('offerrequests.material_id', $request->material);
})->get();
try below ...Instead of orwhere try andWhere
$transactions = $transactions->where(function ($query) use ($request) {
$query->where('advertisements.material_id', $request->material)
->andWhere('offerrequests.material_id', $request->material);
})->get();
or
$transactions = $transactions ->where('advertisements.material_id', $request->material);
$transactions = $transactions ->where('offerrequests.material_id', $request->material);
$transactions = $transacions ->get();

Combining inner join and where statements in Eloquent

I am trying to convert the following database query to use Eloquent:
$orderitems = DB::table('order_items')
->join('orders', 'orders.id', '=', 'order_items.order_id')
->where('orders.status', 1)
->where('order_items.sku', $sku)
->select('order_items.*')
->get();
I've tried the following:
$orderitems = Item::where('sku', $sku)
->with(['order' => function ($query) {
$query->where('status', 0);
}])
->get();
but it seems to be bringing back more results than it should. I can see from using DB::getQueryLog that the order_items query is not joining with the orders table:
select * from `order_items` where `stock_code` = ? and `order_items`.`deleted_at` is null
Do I need to create a new relationship between orderitems and order and add the additional where into that?
Relationships:
Order hasMany Items
Item hasOne Order
Solution was to use Query Scopes https://laravel.com/docs/5.7/eloquent#query-scopes
In the controller:
$orderitems = Item::stock($sku)->paginate(10);
In the orderitems model:
public function scopeStock($query, $sku)
{
return $query->join('orders', function ($join) {
$join->on('orders.id', '=', 'order_items.order_id');
$join->where('orders.status', '=', 1);
})
->select('order_items.*', 'orders.order_date')
->where('order_items.sku', $sku);
}

Laravel query relationship where clause

I need filter by departamento, like where('departamento_id', '=', 1).
Tables:
membro_bancas
id
departamento_id
user_id
trabalhos
id
titulo
orientador_id (references id of membro_bancas)
coorientador_id (references id of membro_bancas)
I have this code:
$trabalho = Trabalho::with('membrobanca.departamento')
->with('coorientador')
->with('academico')
->get();
And returns this:
I got it!
I needed add orWhereHas for coorientador too. The result is this:
Trabalho::whereHas('membrobanca', function($q) use ($departamento_id) {
$q->where('departamento_id', '=', $departamento_id);
})
->orWhereHas('coorientador', function($q) use ($departamento_id) {
$q->where('departamento_id', '=', $departamento_id);
})
->with('academico')
->get();
Try this eloquent filter using whereas
$trabalho = Trabalho::whereHas('membrobanca',function($query) use ($id){
$query->where('departamento_id', '=', $id)
})
->with('coorientador')
->with('academico')
->get();
example of filter using with
$trabalho = Trabalho::with(['membrobanca',function($query) use ($id){
$query->where('departamento_id', '=', $id)
}])
->with('coorientador')
->with('academico')
->get();

selecting all fields from secondary table in eloquent

Is there any reason why my query doesn't end?, I try to get all the values from the secondary table in a join in eloquent:
Product::leftJoin('brands', 'products.brand_id', '=', 'brands.id')
->leftJoin('product_categories', function($query) use ($parent){
$query->on('products.category_id', '=', 'product_categories.id')
->where('product_categories.parent_id', $parent);
})
->selectRaw('brands.*')
->groupBy('brands.id')
->get();
If I select products.* the query goes fine, but with brands.* it never ends, Does someone knows what is happening?
If i run the sql directly in phpmyadmin, it gives me the result.
What i need with this query is to get all brands with existing products that its category has parent_id = $parent
Well i don't know why eloquent has a problem with getting the fields from the second table, but I used query builder so this query work. I leave my "solution", maybe it is useful to someone:
$brands = Product::leftJoin('brands', 'products.brand_id', '=', 'brands.id')
->leftJoin('product_categories', function($query) use ($parent){
$query->on('products.category_id', '=', 'product_categories.id')
->where('product_categories.parent_id', $parent);
})
->selectRaw('brands.*')
->groupBy('brands.id');
$bindings = $brands->getBindings();
$sql = $brands->toSql();
$sql = vsprintf(str_replace('?', '%s', $sql), $bindings);
$brands = \DB::select($sql);

Laravel Eloquent query get users from another model

I have another table called tableb and it has a user relationship defined through the user_id field.
I want to run a query against tableb where a certain date is within a certain range but then I want to grab the user table associated with that row but I only want it to grab the user if it's not been grabbed yet. I'm trying to do this all in 1 DB query. I have most of it done, but I'm having trouble with the unique part of it.
Here's what I have right now:
$tableB = TableB::select('users.*')
->join('users', 'tableb.user_id', '=', 'users.id')
->where('tableb.start_date', '>', date('Y-m-d'))
->get();
So right now I have 3 entries in tableB from the same user, and ideally I'd like to only get 1 entry for that user.
How would I go about doing this?
Since you're selecting only users data, just add a groupBy clause in your query.
$tableB = TableB::select('users.*')
->join('users', 'tableb.user_id', '=', 'users.id')
->where('tableb.start_date', '>', date('Y-m-d'))
->groupBy('users.id')
->get();
You should just add groupBy like this :
$tableB = TableB::select('users.*')
->join('users', 'tableb.user_id', '=', 'users.id')
->where('tableb.start_date', '>', date('Y-m-d'))
->groupBy('users.id')
->get
Try This Code
App/user.php
public function getrelation(){
return $this->hasMany('App\tableB', 'user_id');
}
In Your Controller
Controller.php
use App/user;
public funtion filterByDate(user $user)
{
$date = '2016-02-01';
$result = $user->WhereHas('getrelation', function ($query) use($date) {
$query->whereDate('tableb.start_date', '>', $date)
->first();
});
}

Categories