Eloquent: Count row base on table relation - php

I have no idea how to solve this problem using Laravel Eloquent. So, I posted my question here.
I have tables like this:
+-------------+ +------------------------+
| POSTS | | COMMENTS |
|-------------| |------------------------|
| id | title | | id | text | post_id |
|-----+-------| |----+-------------------|
| 1 | A | | 1 | Lorem | 1 |
| 2 | B | | 2 | Ipsum | 1 |
+-------------+ | 3 | Dolor | 1 |
| 4 | Sit | 1 |
| 5 | Amet | 2 |
| 6 | Lorem 2 | 2 |
+------------------------+
I currently have 2 models, Post model
class Post extends Model
{
public function comment() {
$this->hasMany('App\Comment');
}
}
and Comment model
class Comment extends Model
{
public function comment() {
$this->belongsTo('App\Post');
}
}
The question is, What should I do on the controller so I can make each post has a comment count result? Or simply, just like the table below.
+-----------------------------------------+
| COMMENT COUNT |
|-----------------------------------------|
| posts.id | count(comments.post_id) AS n |
|----------+------------------------------|
| 1 | 4 |
| 2 | 2 |
+-----------------------------------------+
Thanks.

You forgot to return the relationships. So, the models should be defined as:
class Post extends Model
{
public function comments()
{
return $this->hasMany('App\Comment');
}
}
class Comment extends Model
{
public function post()
{
return $this->belongsTo('App\Post');
}
}
Now you can count the post comments as:
echo $post->comments()->count();
or even
echo $post->comments->count();
The difference between these 2 methods is that the latest one is getting and caching the post comments as well.

Related

How to filter post by category in laravel?

I am currently trying to make a relation between 3 tables.
post
id
name
category
id
name
post_category
id
post_id
category_id
Database
post
| 1 | post1 |
| 2 | post2 |
| 3 | post3 |
category
| 1 | cat1 |
| 2 | cat2 |
| 3 | cat3 |
post_category
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 3 | 2 |
| 3 | 2 | 2 |
| 3 | 1 | 3 |
Model Post.php
public function getCategory()
{
return $this->belongsToMany(Category::class, 'post_category');
}
PostController.php
$data = Post::with('getCategory')->get();
It returns correct post list.
Now i want to filter the post by category. I try, but it not working
$categoryId = [1,2];
$data = Post::with('getCategory')->whereHas('category', function ($query) use ($categoryId) {
$query->whereIn('id', $categoryId);
})->orderBy('id','DESC')->get();
please help me
use Laravel 5.4
apparently everything is fine!
One suggestion is to add two more parameters to the belongsToMany method, like:
public function getCategory()
{
return $this->belongsToMany(Category::class, 'post_category', 'post_id', 'category_id');
}
https://laravel.com/api/7.x/Illuminate/Database/Eloquent/Concerns/HasRelationships.html#method_belongsToMany
You should rename your getCategory() function to simply category(). That makes the relation names much more straightforward and probably fixes your issue.
THEN, you should be able to call whereHas('category', ...).
If it still does not work, simply chain a ->toSql() to any of your queries and debug the actual query that way.

How can I write a relation for pivot table in Laravel?

Here is my table structure:
// tickets
+----+------------+----------------------+--------+---------+-------------------+
| id | subject | content | closed | user_id | unique_product_id |
+----+------------+----------------------+--------+---------+-------------------+
| 1 | subject1 | question1 | 0 | 123 | 2 |
+----+------------+----------------------+--------+---------+-------------------+
// unique_product
+----+---------------+------------+
| id | serial_number | product_id |
+----+---------------+------------+
| 1 | 2342rd34fc | 3 |
| 2 | fg34gt4r5t | 1 |
| 3 | 34ffvv4et6 | 3 |
+----+---------------+------------+
// products
+----+--------------+
| id | name |
+----+--------------+
| 1 | Router-rb51 |
| 2 | Switch-sfx2 |
| 3 | Router-rb300 |
+----+--------------+
Now I have a collection of tickets like this:
$tickets = tickets::where(user_id, "$user_id")->get();
foreach( $tickets as $ticket ){
$ticket->{I need to get the name of product here}
}
I can write a relation in the tickets model like this:
public function unique_product()
{
return $this->hasOne(unique_product::class, 'id', 'unique_product_id');
}
And I need one more relation to the products table for getting the name of product (i.e. Switch-sfx2). How should I write that relation?
$tickets = tickets::where(user_id, "$user_id")->with('unique_product.product')->get();
You can take advantage eager loading using with().
but for using with('unique_product.product') You have to define the relation ships between unique_products and products.
In your UniqueProduct model create a new relationship
public function product()
{
return $this->BelongsTo(Product::class, 'id', 'product_id');
}
After that you can access the column of a name like
foreach( $tickets as $ticket ){
$ticket->unique_product->product->name
}

laravel 5.1 MorphToMany & MorphByMany with custom fields

I am having custom fields in table and want to MorpTohmany with other tables. how to do it with custom fields.
In below model (salepurchase) request_to is supplier model foreign key, where salepurchase_type and salepurchase_id these will contain other model relation, Like Warehouse, Shop etc
SalePurchase Model
+----+------------+-------------------+-----------------+-------------+
| id | request_to | salepurchase_type | salepurchase_id | total_items |
+----+------------+-------------------+-----------------+-------------+
| 1 | 1 | Warehouse | 1 | 10 |
| 2 | 1 | Warehouse | 1 | 10 |
| 3 | 1 | Warehouse | 1 | 11 |
| 4 | 1 | Shop | 7 | 15 |
| 5 | 1 | Shop | 5 | 19 |
+----+------------+-------------------+-----------------+-------------+
Warehouse Model
+----+-------------+
| id | name |
+----+-------------+
| 1 | warehosue 1 |
| 2 | warehosue 2 |
Shop Model
+----+-------------+
| id | name |
+----+-------------+
| 5 | Shop 1 |
| 7 | Shop 2 |
Supplier Model
+----+--------------------------+
| id | qualified_person |
+----+--------------------------+
| 1 | Marks |
| 2 | test |
+----+--------------------------+
In your models, just add the relationship:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class SalePurchase extends Model
{
/**
* Get all of the owning salepurchase models.
*/
public function salepurchase()
{
return $this->morphTo();
}
public function supplier()
{
return $this->belongsTo('App\Supplier','request_to','id');
}
}
Then in the other Models:
class Shop extends Model
{
/**
* Get all of the Shop's purchases.
*/
public function salepurchases()
{
return $this->morphMany('App\SalePurchase', 'salepurchase');
}
}
In your Supplier Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Supplier extends Model
{
public function salepurchases()
{
return $this->hasMany('App\SalePurchases');
}
}
I do not see a need to MorphedByMany here. As the SalePurchases table hold the Morphed fields.

Laravel Eloquent how to return one to many to many collection

Is it possible to get an eloquent relation based on a One->Many->Many relationship? In the below example, I would want to get all of the gallery_votes for a given user.
users
+----+---------------+
| id | user_name |
+----+---------------+
| 1 | bob |
| 2 | sam |
+----+---------------+
galleries
+----+---------------+-----------+
| id | gallery_name | user_id |
+----+---------------+-----------+
| 1 | Alaska Pics | 1 |
| 2 | Texas Pics | 1 |
| 3 | California | 2 |
| 4 | Cars | 2 |
+----+---------------+-----------+
gallery_votes
+----+---------------+--------+
| id | gallery_id | vote |
+----+---------------+--------+
| 1 | 1 | 1 |
| 2 | 1 | 1 |
| 3 | 1 | 1 |
| 4 | 2 | 1 |
+----+---------------+--------+
The relationships are setup as follows.
class User extends Model implements AuthenticatableContract, CanResetPasswordContract {{
...
public function galleries()
{
return $this->hasMany('App\Gallery');
}
}
and
class Gallery extends Model {
....
public function votes()
{
return $this->hasMany('App\GalleryVote');
}
}
$user->galleries returns a collection of associated galleries, so that works correctly. and $gallery->votes returns a collection of associate votes, so that also works correctly. But $user->galleries->votes gives
Undefined property: Illuminate\Database\Eloquent\Collection::$votes on line 1
Is what I'm trying to do even possible with straight Laravel? Or do I need to write the SQL directly?
The "has many through" relation provides a convenient short-cut for accessing distant relations via an intermediate relation.
class User extends Model implements AuthenticatableContract, CanResetPasswordContract {{
...
public function galleries()
{
return $this->hasMany('App\Gallery');
}
public function votes()
{
return $this->hasManyThrough('App\GalleryVote', 'App\Gallery');
}
}
Now $user->votes will return all votes for that user. Remember you need to create the GalleryVote eloquent model as well.
You can read more about that type of relation, as well as some example usage in the documentation.

Laravel getting results from model belongsToMany relationship back to controller

I'm using Laravel 5 and Eloquent, I have 3 tables setup:
photos
+----+---------------+------------------+
| id | photo_name | photo_location |
+----+---------------+------------------+
| 1 | kittens.jpg | C:\kittens.jpg |
| 2 | puppies.jpg | C:\puppies.jpg |
| 3 | airplanes.jpg | C:\airplanes.jpg |
| 4 | trains.jpg | C:\trains.jpg |
+----+---------------+------------------+
photo_set (pivot table)
+------------+----------+
| set_id | photo_id |
+------------+----------+
| 1 | 1 |
| 1 | 2 |
| 2 | 3 |
| 2 | 4 |
+------------+----------+
sets
+----+----------------+
| id | description |
+----+----------------+
| 1 | cute animals |
| 2 | transportation |
+----+----------------+
I created a belongsToMany relationship in my photos and sets models to link these two together.
class Photo extends Model {
public function sets()
{
return $this->belongsToMany('App\Set');
}
}
and
class Set extends Model {
public function photos()
{
return $this->belongsToMany('App\Photo');
}
}
However I'm trying to reference the $Sets->photos() model function in my controller, so that given a set of id=1, I can return the photo_location value for each row [C:\kittens.jpg,C:\puppies.jpg], but I don't know how to access it..
Also, I can "sort of" access this information in the view with:
#foreach($sets as $set)
{{$set->images}}
#endforeach
but it looks like it only iterates through once and returns a json (?) of the necessary information, though I'm not sure how to parse that to regular HTML either.
So in short, I'm having trouble accessing this data (photo_location) from both the controller and the view
Use Collection::lists()
$locations = Set::find(1)->photos->lists('photo_location');
It will return an array ['C:\kittens.jpg', 'C:\puppies.jpg']
http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Collection.html#method_lists
In your controller try this :
$result = PhotoSet::where('set_id', $set_id)
->with('sets')
->with('photos')
->get();
$photo_location = $result->photos->photo_location;
here PhotoSet is the model for photo_set table, because it is a pivot table we will be able to access both sets and photos table from it.

Categories