I have 3 table products, details and
detail_colors
I want select max "stock" from "detail_colors" and
max "price" from "details"
$products = Product::
join('details', function (JoinClause $join) {
$join->on('products.id', '=', 'details.product_id');
})
->join('detail_colors', function (JoinClause $join) {
$join->on('products.id', '=', 'detail_colors.product_id');
})
->select('products.*', DB::raw('max(details.price) as price'), DB::raw('max(detail_colors.stock) as stock'))
and its not working.
I use laravel 8.*
Can't you use aggregate functions on relationships?
$products = Product::query()
->withMax('details', 'price')
->withMax('detail_colors', 'stock')
Or you can define the relationship as such:
public function details()
{
return $this->hasOne(Details::class)->ofMany('price', 'max');
}
public function details()
{
return $this->hasOne(DetailColors::class)->ofMany('stock', 'max');
}
Related
I am trying to query two tables in a database but its returning this error.
I am trying to implement a search through multiple tables. The project is an online store with 3 distinctive tables, Products, Categories and Brands. I can only search through the Products table but can't seem to get the same search field from my blade file to search either the categories or the brands and return results of the associated products.
QLSTATE[23000]: Integrity constraint violation: 1052 Column 'status' in where clause is ambiguous (SQL: select * from `categories` inner join `products` on `products`.`category_id` = `categories`.`id` where `name` LIKE %Television% and `status` = 1)
My Search function
public function searchProducts(Request $request) {
$product = $request->input('product');
$categories = Category::with('categories')->where(['parent_id' => 0])->get();
$productsAll = Category::query()->join('products', 'products.category_id', '=', 'categories.id')
->where('name', 'LIKE', "%{$product}%")
->where('status', 1)->get();
$breadcrumb = "<a href='/'>Home</a> / ".$product;
return view('pages.results')->with(compact('categories','productsAll','product','breadcrumb'));
}
My Category Model
class Category extends Model implements Searchable
{
protected $table = 'categories';
protected $fillable = [
'name'
];
public function categories(){
return $this->hasMany('App\Category','id');
}
public function products(){
return $this->hasMany('App\Product','id');
}
}
My Products Model
class Product extends Model implements Searchable
{
public function category() {
return $this->hasMany('App\Category', 'id') ;
}
public function attributes(){
return $this->hasMany('App\Product','id');
}
}
You have status column in more than one table.
Change this
->where('status', 1)->get();
to this
->where('products.status', 1)->get();
I was able to solve it by modifying my search function as follows.
public function searchProducts(Request $request) {
$product = $request->input('product');
$categories = Category::with('categories')->where(['parent_id' => 0])->get();
$productsAll = Category::query()->join('products', 'products.category_id', '=', 'categories.id')
->where('categories.name', 'LIKE', "%{$product}%")
->orWhere('products.product_name', 'LIKE', "%{$product}%")
->where('products.status', 1)->get();
$breadcrumb = "<a href='/'>Home</a> / ".$product;
return view('pages.results')->with(compact('categories','productsAll','product','breadcrumb'));
}
I am trying to return a view with 2 tables, orders and order_menu. What I want to do is to display what orders the customer ordered based on order_id to my view.
Here is the database table for orders and this is database table for order_menu.
I've tried using join table in my controller but it won't work. Here is my controller:
public function show(Order $order)
{
$data = DB::table('order_menu')
->join('menus', 'menus.id', '=', 'order_menu.menu_id')
->join('orders', 'orders.id', '=', 'order_menu.order_id')
->select('orders.*', 'menus.name', 'order_menu.quantity')
->get();
return view('admin.order.detail')->with([
'order' => $order,
'data' => $data,
]);
}
Is there any solutions to solve this?
You just need to add a filter for order id in your query, I assume $order is the instance of model and has order data
$data = DB::table('order_menu')
->join('menus', 'menus.id', '=', 'order_menu.menu_id')
->join('orders', 'orders.id', '=', 'order_menu.order_id')
->select('orders.*', 'menus.name', 'order_menu.quantity')
->where('orders.id', $order->id)
->get();
Or if you already have relations in place in your model then using eloquent you can query the data as
class Order extends Model
{
public function menus()
{
return $this->belongsToMany(Menu::class, 'order_menu ', 'order_id', 'menu_id')->withPivot('quantity');
}
}
class Menu extends Model
{
public function orders()
{
return $this->belongsToMany(Order::class, 'order_menu ', 'menu_id','order_id');
}
}
$data = Order::with('menus')->find($order->id);
public function show(Order $order)
{
$data = DB::table('orders*')
->join('order_menu*', 'order_menu.id', '=', 'orders.id')
->groupBy('orders.id')
->get();
return view('admin.order.detail')->with([
'data' => $data,
]);
}
Have a query, how I can filter results by translation relation (by name column)
$item = Cart::select('product_id','quantity')
->with(['product.translation:product_id,name','product.manufacturer:id,name'])
->where($cartWhere)
->get();
my model
Cart.php
public function product($language = null)
{
return $this->hasOne('App\Models\Product','id','product_id');
}
Product.php
public function translations()
{
return $this->hasMany('App\Models\ProductTranslation','product_id','id');
}
Update v1.0
do like this, but query takes too long time
$item = Cart::select('product_id','quantity')
->with(['product.translation', 'product.manufacturer:id,name'])
->where($cartWhere)
->when($search,function ($q) use ($search) {
$q->whereHas('product.translation', function (Builder $query) use ($search) {
$query->where('name', 'like', '%'.$search.'%');
$query->select('name');
});
}
)
->get() ;
Inside the array within your with() method, you can pass a function as a value.
Cart::select('product_id','quantity')
->with([
'product', function($query) {
$query->where($filteringAndConditionsHere);
}
]);
https://laravel.com/docs/7.x/eloquent-relationships#eager-loading
$users = User::with('departments')
->whereHas('departments', function ($q) use ($departments) {
return $q->whereIn('department_id', $departments);
})->whereNotNull('users.email')
->get();
public function users(){return $this->morphedByMany(User::class, 'departmentable');}
in department model
and
public function departments(){return $this->morphToMany(Department::class, 'departmentable');
}
in user model
in your whereIn statement you use department_id column in departments table, are you sure of this, isn't just 'id' ('departments.id')?
$users = User::with('departments')
->whereHas('departments', function ($q) use ($departments) {
return $q->whereIn('departments.id', $departments);
})->whereNotNull('users.email')
->get();
How do I create brackets around my orWhere:
public function categories()
{
return $this->belongsToMany('App\Category', 'user_category')->orWhere('default', 1);
}
So it is converted to this:
where (`user_category`.`user_id` = ? or `default` = 1)
Currently the brackets here are missing and mess up the whole query. I tried for example:
public function categories()
{
$join = $this->belongsToMany('App\Category', 'user_category')
->orWhere('default', 1);
return $this->where(function ($query) use ($join) {
return $join;
});
}
But here I am loosing my model and getting Call to undefined method Illuminate\Database\Query\Builder::...
You can use advanced where clause like:
Model::where(function ($query) {
$query->where('a', '=', 1)
->orWhere('b', '=', 1);
})->where(function ($query) {
$query->where('c', '=', 1)
->orWhere('d', '=', 1);
});
Or nested clause like:
Model::where(function($query)
{
$query->where('a', 'like', 'keyword');
$query->or_where('b', 'like', 'keyword');
})
->where('c', '=', '1');
Are you trying to get all the categories related to an user and the categories where the default field is 1?
If that is the case:
public function categories()
{
return $this->belongsToMany('App\Category');
}
public function relatedCategories()
{
return App\Category::all()->where('default',1)->merge($this->categories);
}
The relatedCategories() method should return a collection with the desired categories. Take in care that the non-related categories but with default=1 will not have the pivot object, because these categories doesn't exist in your pivot table.