I have the following tables
items ( id, item-name, catalog-name)
categories (id, category-name)
item_categories ( pivot table )
on Items model I made this relation
public function itemCategories()
{
return $this->belongsToMany('App\Models\Categories');
}
In my controller I want to search all items from a catalog that belong to categories so i am trying this
$items = Items::where('catalog-name', 'somename')->whereHas('itemCategories', function ($query) {
$query->where('category', 'something');
});
But I keep getting the error
Call to undefined method App\Models\Items::itemCategories()
Any ideas what I am doing here ?
Related
I have an orders table, an items table, and a pivot table called item_order which has two custom fields (price, quantity). The relationship between Order and Item is belongsToMany. I'm trying to return the count of all items with an id of 1, where the parent Order->status == 'received'. For the life of me, I can't figure out how to do this.
class Order extends Model
{
public function items()
{
return $this->belongsToMany(Item::class)->withPivot('price', 'quantity');
}
}
class Item extends Model
{
public function orders()
{
return $this->belongsToMany(Order::class)->withPivot('price', 'quantity');
}
}
Try this:
$total_quantity = Item::find(1) // getting the Item
->orders() // entering the relationship
->with('items') // eager loading related data
->where('status', '=', 'received') // constraining the relationship
->get() // getting the results: Collection of Order
->sum('pivot.quantity'); // sum the pivot field to return a single value.
The strategy here is to find the desired Item to then get the related Orders to this Item that has a 'received' status, to finally sum the pivot attribute in order to get a single value.
It should work.
Considering you know the id of the item, most performant way would be to query item_order table directly. I would create a pivot model for ItemOrder and define the belongsTo(Order::class) relationship and do this:
$sum = ItemOrder::where('item_id', $someItemId)
->whereHas('order', function ($q) {
return $q->where('status', 'received');
})
->sum('quantity');
I have two models, Product and Filter.
A product can have many filters and one filter can have many products. Many to Many relationship.
In my Product I have:
public function filters () {
return $this->belongsToMany('App\Models\Filter');
}
And in my Filter:
public function products () {
return $this->belongsToMany('App\Models\Product')->withTimestamps();
}
When I try to insert a product and after save the filters like this:
$filtersId = $request->filter;
$product->filters()->attach($filtersId);
I've gotten this error:
Base table or view not found: 1146 Table 'pontocom-moveis.filter_product' doesn't exist (SQL: insert into `filter_product` (`filter_id`, `product_id`) values (1, 31))
How can I change the order to product_filter?
The second parameter of the method is the table name.
So in this case you should use:
public function filters () {
return $this->belongsToMany('App\Models\Filter', 'product_filter');
}
public function products () {
return $this->belongsToMany('App\Models\Product', 'product_filter')->withTimestamps();
}
You should create the table : filter_product with attributes :
filter_id and product_id
I have two models:
class Order extends Eloquent
{
public function User()
{
return $this->belongsTo('User');
}
public function Product()
{
return $this->belongsToMany('Product');
}
}
and the second one is:
class Product extends Eloquent
{
public function Order()
{
return $this->belongsToMany('Order');
}
}
My question is how can i access a value of second table column using pivot table:
product table:
id
title
image
order table:
id
status
pivot table(order_product):
id
product_id
order_id
I need to access title column of products from orders. for example if a user orders many products in one order I can fetch all product title and show theme.
I don't like use join , instead I like to use Laravel functionality itself.
I found the answer:
$orders = Order::orderBy('created_at', 'DESC')->paginate($page_number);
foreach($orders as $item){
foreach($item->product as $item){
{{$item->title}}<br>
}
}
I can access products from order.
Want to get selected columns, when querying through pivot table. Following is my scenario.
I have 3 tables,
coupons
coupon_cities
cities
relationship details are as following.
class Coupon extends Eloquent {
public function cities(){
return $this->belongsToMany('City', 'coupon_cities', 'coupon_id', 'city_id');
}
}
When I query
Coupon::with('cities')
it returns array of all columns of city table for each entry of coupon row
The only way is this:
$coupon = Coupon->first();
$coupon->cities()->get([your columns here]);
Normally you'd do it like below:
Coupon::with(['cities' => function ($q)
{
$q->select('column', 'column2' ...);
}
However it won't work for belongsToMany relation -> https://github.com/laravel/framework/pull/4440
I have 3 Models... Category, Post, Vote
When viewing a category, I am showing an index of all Posts in that category. So I'm doing something like foreach ($category->posts as $post) in my view.
The question I have now is how can I order the posts based on the sum of votes they have?
I have standard relationships setup, so that a post hasMany votes.
You can do it either by defining a helper relation on the Post model and sorting the collection after the relation is loaded OR simply by joining the votes and ordering in the query.
1 RELATION
// Post model
public function votesSum()
{
return $this->hasOne('Vote')->selectRaw('post_id, sum(votes) as aggregate')->groupBy('post_id');
}
// then
$category->posts->load('votesSum'); // load relation on the collection
$category->posts->sortByDesc(function ($post) {
return $post->votesSum->aggregate;
});
// access votes sum like this:
$category->posts->first()->votesSum->aggregate;
2 JOIN
$category->load(['posts' => function ($q) {
$q->leftJoin('votes', 'votes.post_id', '=', 'posts.id')
->selectRaw('posts.*, sum(votes.votes) as votesSum')
->groupBy('posts.id')
->orderBy('votesSum', 'desc');
}]);
// then access votes sum:
$category->posts->first()->votesSum;
You can use scope for that:
// Post model
public function scopeOrderByVotes($query)
{
$query->leftJoin('comments','comments.post_id','=','posts.id')
->selectRaw('posts.*,sum(comments.id) as commentsSum')
->groupBy('posts.id')
->orderBy('commentsSum','desc');
}
// then
$category = Category::with(['posts' => function ($q) {
$q->orderByVotes();
}])->whereSlug($slug)->firstOrFail();